电商项目10:商品管理、仓库管理

1、商品管理

1.1、spu检索

1.1.1、后端

spu检索接口文档
在这里插入图片描述

SpuInfoController

/**
     * 列表
     */
    @RequestMapping("/list")
    // @RequiresPermissions("product:spuinfo:list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = spuInfoService.queryPageCondition(params);

        return R.ok().put("page", page);
    }

SpuInfoService

PageUtils queryPageCondition(Map<String, Object> params);

SpuInfoServiceImpl

 @Override
    public PageUtils queryPageCondition(Map<String, Object> params) {
        QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();
        // 关键字检索
        Object key = params.get("key");
        // 三级分类id
        Object catalogId = params.get("catalogId");
        // 品牌id
        Object brandId = params.get("brandId");
        // 状态 0-新建 1-上架 2-下架
        Object status = params.get("status");
        if (!StringUtils.isEmpty(key)){
            wrapper.and((w) -> {
                w.eq("id",key).or().like("spu_name",key);
            });
        }
        if (!StringUtils.isEmpty(catalogId)){
            wrapper.eq("catalog_id",catalogId);
        }
        if (!StringUtils.isEmpty(brandId)){
            wrapper.eq("brand_id",brandId);
        }
        if (!StringUtils.isEmpty(status)){
            wrapper.eq("publish_status",status);
        }

        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

查询时创建时间不是年月日时分秒类型。可以在全局配置文件中配置:

  jackson:
    date-format: yyyy-MM-dd HH:mm:ss

后端代码修改:
SpuInfoServiceImpl

 if (!StringUtils.isEmpty(catalogId) && !"0".equals(catalogId)){
            wrapper.eq("catalog_id",catalogId);
        }
        if (!StringUtils.isEmpty(brandId) && !"0".equals(brandId)){
            wrapper.eq("brand_id",brandId);
        }

1.1.2、前端

前端调用时出现第一次进入页面。搜索时输入框条件未置空,且为0.是因为业务规则,传0就查全部。后端需要改代码。
在这里插入图片描述

1.2、sku检索

1.2.1、后端

sku检索
在这里插入图片描述
SkuInfoController

   /**
     * 列表
     */
    @RequestMapping("/list")
    // @RequiresPermissions("product:skuinfo:list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = skuInfoService.queryPageByCondition(params);

        return R.ok().put("page", page);
    }

SkuInfoService

PageUtils queryPageByCondition(Map<String, Object> params);

SkuInfoServiceImpl

 @Override
    public PageUtils queryPageByCondition(Map<String, Object> params) {
        QueryWrapper<SkuInfoEntity> wrapper = new QueryWrapper<>();
        Object key = params.get("key");
        Object catelogId = params.get("catelogId");
        Object brandId = params.get("brandId");
        Object min = params.get("min");
        Object max = params.get("max");
        if (!StringUtils.isEmpty(key)){
            wrapper.and((w) -> {
                w.eq("sku_id",key).or().like("sku_name",key);
            });
        }
        if (!StringUtils.isEmpty(catelogId) && !"0".equals(catelogId)){
            wrapper.eq("catalog_id",catelogId);
        }
        if (!StringUtils.isEmpty(brandId) && !"0".equals(brandId)){
            wrapper.eq("brand_id",brandId);
        }
        if (!StringUtils.isEmpty(min)){
            wrapper.ge("price",min);
        }
        if (!StringUtils.isEmpty(max)){
            BigDecimal bigDecimal = new BigDecimal((String) max);
            if (bigDecimal.compareTo(new BigDecimal("0")) > 0){
                // 当价格区间的最大值大于0才去拼接
                wrapper.le("price",max);
            }
        }
        IPage<SkuInfoEntity> page = this.page(
                new Query<SkuInfoEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

1.3、查询spu规格

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
点击规格。会跑到404.页面。

在这里插入图片描述

解决方案如下:
spu管理规格404问题修复方案

注意和parent_id绑定,建议以菜单按钮新增方式

在这里插入图片描述

1.3.1、后端

AttrController

   /**
     * 获取spu规格
     */
    @RequestMapping("/base/listforspu/{spuId}")
    // @RequiresPermissions("product:attr:list")
    public R getListForspu(@PathVariable Long spuId){
        List<ProductAttrValueEntity> list = attrService.getListForspu(spuId);
        return R.ok().put("data", list);
    }

AttrService

 List<ProductAttrValueEntity> getListForspu(Long spuId);

AttrServiceImpl

@Override
    public List<ProductAttrValueEntity> getListForspu(Long spuId) {
        return productAttrValueService.getBaseMapper().selectList(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id",spuId));
    }

1.3.2、前端

接口有返回数据。但前端未正常回显
在这里插入图片描述

解决方案如下:
前端+后端此接口修改方式
根据此文档修改以后

重新新增一个商品

可以正常回显了。但是多次点击又不能正常回显。

在这里插入图片描述
第二、第三次进来又为空
在这里插入图片描述

因为延迟加载问题。使用延迟函数即可修复此问题
在这里插入图片描述

1.4、修改spu规格

在这里插入图片描述

AttrController

/**
     * 获取spu规格
     */
    @PostMapping("/update/{spuId}")
    // @RequiresPermissions("product:attr:list")
    public R updateProductSpu(@PathVariable Long spuId,@RequestBody List<ProductAttrValueEntity> entityList){
        attrService.updateProductSpu(spuId,entityList);
        return R.ok();
    }

AttrService

void updateProductSpu(Long spuId, List<ProductAttrValueEntity> entityList);

AttrServiceImpl

 @Transactional
    @Override
    public void updateProductSpu(Long spuId, List<ProductAttrValueEntity> entityList) {
        // 删除后新增
        // 1、根据spuId删除spu属性值表
        productAttrValueService.getBaseMapper().delete(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id",spuId));
        // 2、批量新增
        entityList = entityList.stream().map(entity -> {
            entity.setSpuId(spuId);
            return entity;
        }).collect(Collectors.toList());
        productAttrValueService.saveBatch(entityList);
    }

2、库存管理

2.1、启动ware后端微服务

application.yml

  application:
    name: gulimall-ware

GulimallWareApplication

@SpringBootApplication
@EnableDiscoveryClient
@EnableTransactionManagement
@MapperScan("com.ljs.gulimall.ware.dao")
public class GulimallWareApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallWareApplication.class, args);
    }

}

启动ware服务。登录nacos

在这里插入图片描述
代表已经注册成功

gulimall-gateway配置路由规则

application.yml

   - id: ware_route
            #负载均衡到member服务
     uri: lb://gulimall-ware
     predicates:
        - Path=/api/ware/**
              #网关重写
     filters:
        - RewritePath=/api/(?<segment>.*),/$\{segment}

在这里插入图片描述

2.2、仓库维护查询

仓库列表
WareInfoServiceImpl

@Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<WareInfoEntity> wrapper = new QueryWrapper<>();
        Object key = params.get("key");
        if (!StringUtils.isEmpty(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);
    }

2.3、查询商品库存

查询商品库存
WareSkuServiceImpl

 @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<WareSkuEntity> wrapper = new QueryWrapper<>();
        Object skuId = params.get("skuId");
        if (!StringUtils.isEmpty(skuId)){
            wrapper.eq("sku_id",skuId);
        }
        Object wareId = params.get("wareId");
        if (!StringUtils.isEmpty(wareId)){
            wrapper.eq("ware_id",wareId);
        }
        IPage<WareSkuEntity> page = this.page(
                new Query<WareSkuEntity>().getPage(params),
                wrapper
        );
        return new PageUtils(page);
    }

2.4、查询采购需求

查询采购需求

PurchaseDetailServiceImpl

 @Override
 public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<PurchaseDetailEntity> wrapper = new QueryWrapper<>();
        Object key = params.get("key");
        if (!StringUtils.isEmpty(key)){
            wrapper.and((w) -> {
               w.eq("id",key).or().eq("sku_id",key).or().eq("sku_num",key);
            });
        }
        Object status = params.get("status");
        if (!StringUtils.isEmpty(status)){
            wrapper.eq("status",status);
        }
        Object wareId = params.get("wareId");
        if (!StringUtils.isEmpty(wareId)){
            wrapper.eq("ware_id",wareId);
        }
        IPage<PurchaseDetailEntity> page = this.page(
                new Query<PurchaseDetailEntity>().getPage(params),
                wrapper
        );
        return new PageUtils(page);
    }

2.5、合并采购单

在这里插入图片描述

查询未领取的采购单

PurchaseController

 /**
     * 列表
     */
    @RequestMapping("/unreceive/list")
    // @RequiresPermissions("ware:purchase:list")
    public R unreceiveList(@RequestParam Map<String, Object> params){
        PageUtils page = purchaseService.queryUnReceivePage(params);
        return R.ok().put("page", page);
    }

PurchaseService

PageUtils queryUnReceivePage(Map<String, Object> params);

PurchaseServiceImpl

@Override
    public PageUtils queryUnReceivePage(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> wrapper = new QueryWrapper<>();
        wrapper.and(item -> {item.eq("status",1).or().eq("status",0);});
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                wrapper
        );
        return new PageUtils(page);
    }

在这里插入图片描述
这里显示有问题是因为没有绑定好采购人员信息

在这里插入图片描述

在这里插入图片描述

分配好以后再点击合并采购单

就能正常显示了
在这里插入图片描述
在这里插入图片描述
需要编写此接口

##合并采购单有两种方式
1、选择到采购单
在这里插入图片描述
在这里插入图片描述
会传采购单id

2、不选择采购单,它会自己创建一个采购单进行合并
在这里插入图片描述
在这里插入图片描述

合并采购需求

PurchaseController

 /**
     * 合并采购需求
     */
    @RequestMapping("/merge")
    // @RequiresPermissions("ware:purchase:list")
    public R merge(@RequestBody PurchaseMergeEntity mergeEntity){
        purchaseService.merge(mergeEntity);
        return R.ok();
    }

PurchaseService

 void merge(PurchaseMergeEntity mergeEntity);

PurchaseServiceImpl

  @Transactional
    @Override
    public void merge(PurchaseMergeEntity mergeEntity) {
        Long purchaseId = mergeEntity.getPurchaseId();
        if (purchaseId == null){
            // 新建合并单
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setStatus(PurchaseEnum.CREATED.getCode());
            this.save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        }
        // 修改合并项信息
        List<Long> items = mergeEntity.getItems();
        Long finalPurchaseId = purchaseId;
        List<PurchaseDetailEntity> collect = items.stream().map(
                (id) -> {
                    PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
                    purchaseDetailEntity.setId(id);
                    purchaseDetailEntity.setPurchaseId(finalPurchaseId);
                    purchaseDetailEntity.setStatus(PurchaseDetailEnum.ASSIGNED.getCode());
                    return purchaseDetailEntity;
                }
        ).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(collect);
        // 更新采购单更新时间
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(purchaseId);
        purchaseEntity.setUpdateTime(new Date());
        this.updateById(purchaseEntity);
    }

合并采购单id
在这里插入图片描述
不选择采购单id会新增采购单
在这里插入图片描述

2.6、领取采购单

领取采购单

PurchaseController

   /**
     * 领取采购单
     */
    @PostMapping("/received")
    // @RequiresPermissions("ware:purchase:list")
    public R merge(@RequestBody List<Long> ids){
        purchaseService.received(ids);
        return R.ok();
    }

PurchaseServiceImpl

    @Transactional
    @Override
    public void received(List<Long> ids) {
        // 1、确认当前采购单是否新建或已分配状态
        List<PurchaseEntity> collect = ids.stream().map(this::getById).
                filter(item -> {
                    if (PurchaseEnum.CREATED.getCode().equals(item.getStatus()) || PurchaseEnum.ASSIGNED.getCode().equals(item.getStatus())) {
                        return true;
                    }
                    return false;
                }).map(item -> {
            item.setUpdateTime(new Date());
            item.setStatus(PurchaseEnum.RECEIVED.getCode());
            return item;
        }).collect(Collectors.toList());
        // 2、改变采购单状态
        if (collect.size() == 0){
            return;
        }
        this.updateBatchById(collect);
        // 3、改变采购单详情状态
        collect.forEach(item -> {
            List<PurchaseDetailEntity> list = purchaseDetailService.list(new QueryWrapper<PurchaseDetailEntity>().eq("purchase_id", item.getId()));
            List<PurchaseDetailEntity> collect1 = list.stream().map(updateItem -> {
                PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
                detailEntity.setId(updateItem.getId());
                detailEntity.setStatus(PurchaseDetailEnum.RECEIVED.getCode());
                return detailEntity;
            }).collect(Collectors.toList());
            if (collect1.size() > 0){
                purchaseDetailService.updateBatchById(collect1);
            }
        });
    }
   @Transactional
    @Override
    public void merge(PurchaseMergeEntity mergeEntity) {
        Long purchaseId = mergeEntity.getPurchaseId();
        if (purchaseId == null){
            // 新建合并单
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setStatus(PurchaseEnum.CREATED.getCode());
            this.save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        }
        // 合并采购需求时判断合并单新建和已分配状态。其他状态不给合并
        PurchaseEntity entity = this.getById(purchaseId);
        if (entity != null && (!PurchaseEnum.CREATED.getCode().equals(entity.getStatus()) && !PurchaseEnum.ASSIGNED.getCode().equals(entity.getStatus()))){
            throw new RuntimeException("有合并单:" + purchaseId + "不是新建或已分配状态,不允许合并");
        }
        // 修改合并项信息
        List<Long> items = mergeEntity.getItems();
        Long finalPurchaseId = purchaseId;
        List<PurchaseDetailEntity> collect = items.stream().map(
                (id) -> {
                    PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
                    purchaseDetailEntity.setId(id);
                    purchaseDetailEntity.setPurchaseId(finalPurchaseId);
                    purchaseDetailEntity.setStatus(PurchaseDetailEnum.ASSIGNED.getCode());
                    return purchaseDetailEntity;
                }
        ).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(collect);
        // 更新采购单更新时间
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(purchaseId);
        purchaseEntity.setUpdateTime(new Date());
        this.updateById(purchaseEntity);
    }

2.7、完成采购

完成采购

PurchaseController

  /**
     * 完成采购
     */
    @PostMapping("/done")
    // @RequiresPermissions("ware:purchase:list")
    public R done(@RequestBody PurchaseDoneVO purchaseDoneVO){
        purchaseService.done(purchaseDoneVO);
        return R.ok();
    }

PurchaseService

void done(PurchaseDoneVO purchaseDoneVO);

PurchaseServiceImpl

   @Transactional
   @Override
   public void done(PurchaseDoneVO purchaseDoneVO) {
        // 1、改变采购项状态
        List<PurchaseItemDoneVO> items = purchaseDoneVO.getItems();
        items.forEach(item -> {
            PurchaseDetailEntity entity = new PurchaseDetailEntity();
            BeanUtils.copyProperties(item,entity);
            purchaseDetailService.updateById(entity);
        });
        // 2、根据采购项状态改变采购单状态
        boolean flag = true;
        for (PurchaseItemDoneVO item : items) {
            PurchaseDetailEntity entity = new PurchaseDetailEntity();
            entity.setId(item.getItemId());
            if (!PurchaseDetailEnum.FINISHED.getCode().equals(item.getStatus())) {
                flag = false;
                entity.setStatus(PurchaseDetailEnum.HASERROR.getCode());
                purchaseDetailService.updateById(entity);
            } else {
                entity.setStatus(PurchaseDetailEnum.FINISHED.getCode());
                purchaseDetailService.updateById(entity);
                // 3、新增或修改库存
                Long itemId = item.getItemId();
                PurchaseDetailEntity detailEntity = purchaseDetailService.getBaseMapper().selectById(itemId);
                if (detailEntity != null){
                    Long skuId = detailEntity.getSkuId();
                    Integer skuNum = detailEntity.getSkuNum();
                    Long wareId = detailEntity.getWareId();
                    QueryWrapper<WareSkuEntity> wrapper = new QueryWrapper<WareSkuEntity>().eq("sku_id", skuId).eq("ware_id", wareId);
                    List<WareSkuEntity> list = wareSkuService.list(wrapper);
                    WareSkuEntity wareSkuEntity = new WareSkuEntity();
                    BeanUtils.copyProperties(detailEntity,wareSkuEntity);
                    wareSkuEntity.setStock(skuNum);
                    if (list == null || list.size() == 0){
                        // 新增
                        wareSkuEntity.setStockLocked(0);
                        // 调用远程接口获取skuName。并且保证事务不回滚
                        try{
                            R info = productFeignService.info(skuId);
                            if (info.getCode() == 0){
                                Map<String,Object> data = (Map<String, Object>) info.get("skuInfo");
                                wareSkuEntity.setSkuName((String)data.get("skuName"));
                            }
                        }catch (Exception e){

                        }
                        wareSkuEntity.setStock(skuNum);
                        wareSkuService.addStock(wareSkuEntity);
                    } else {
                        // 修改
                        wareSkuService.updateStock(wareSkuEntity);
                    }
                }
            }
        }
        Long id = purchaseDoneVO.getId();
        PurchaseEntity entity = new PurchaseEntity();
        entity.setId(id);
        entity.setStatus(flag ? PurchaseEnum.FINISHED.getCode() : PurchaseEnum.HASERROR.getCode());
        this.updateById(entity);
    }

ProductFeignService

package com.ljs.gulimall.ware.feign;

import com.ljs.gulimall.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient("gulimall-product")
public interface ProductFeignService {
    /**
     * 根据skuId获取sku信息
     *
     * @param skuId skuId
     * @return R
     */
    @RequestMapping("/product/skuinfo/info/{skuId}")
    R info(@PathVariable("skuId") Long skuId);

}

GulimallWareApplication

@EnableFeignClients

WareSkuService

void addStock(WareSkuEntity wareSkuEntity);
void updateStock(WareSkuEntity wareSkuEntity);

WareSkuServiceImpl

    @Override
    public void addStock(WareSkuEntity wareSkuEntity) {
        wareSkuDao.addStock(wareSkuEntity);
    }

    @Override
    public void updateStock(WareSkuEntity wareSkuEntity) {
        wareSkuDao.updateStock(wareSkuEntity);
    }

WareSkuDao

    void addStock(WareSkuEntity wareSkuEntity);

    void updateStock(WareSkuEntity wareSkuEntity);

WareSkuDao.xml

    <insert id="addStock">
        insert into
        wms_ware_sku
        (`sku_id`,`ware_id`,`stock`,`sku_name`,`stock_locked`)
        values
        (#{skuId},#{wareId},#{stock},#{skuName},#{stockLocked})
    </insert>

    <update id="updateStock">
        update
        wms_ware_sku
        set
        stock = stock + #{stock}
        where sku_id = #{skuId}
        and ware_id = #{wareId}
    </update>

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值