day06-【仓库系统】

一、仓储服务

1.1、仓储服务配置

创建会员服务ware命名空间
nacos.yml

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 124.223.14.248:8848
  application:
    name: firefly-ware
server:
  port: 10000

mybatis.yml

mybatis-plus:
  mapper-locations: classpath:/mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

datasource.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://124.223.14.248:3306/firefly_wms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: root

logging.yml

# 日志级别
logging:
  level:
    com.firefly.fireflymall: debug

1.2、网关路由配置

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

1.3、仓库维护

1.3.1、仓库维护-前端

wareinfo.vue




wareinfo-add-or-update.vue




1.3.2、仓库列表-后端

{
   page: 1,//当前页码
   limit: 10,//每页记录数
   sidx: 'id',//排序字段
   order: 'asc/desc',//排序方式
   key: '华为'//检索关键字
}
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
 
        QueryWrapper<WareInfoEntity> wareInfoEntityQueryWrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        if(!StringUtils.isEmpty(key)){
            wareInfoEntityQueryWrapper.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),
                wareInfoEntityQueryWrapper
        );
 
        return new PageUtils(page);
    }
http://localhost:88/api/ware/wareinfo/list
{
    "msg": "success",
    "code": 0,
    "page": {
        "totalCount": 1,
        "pageSize": 10,
        "totalPage": 1,
        "currPage": 1,
        "list": [
            {
                "id": 1,
                "name": "库存",
                "address": "1",
                "areacode": "2"
            }
        ]
    }
}

1.4、商品库存

1.4.1、商品库存-前端

sku.vue

 

sku-add-or-update.vue




1.4.1、查询商品库存-后端

{
   page: 1,//当前页码
   limit: 10,//每页记录数
   sidx: 'id',//排序字段
   order: 'asc/desc',//排序方式
   wareId: 123,//仓库id
   skuId: 123//商品id
}

WareSkuController

    /**
     * 查询商品库存
     *
     * @param params
     * @return
     */
    @GetMapping("/list")
    @RequiresPermissions("ware:waresku:list")
    public R list(@RequestParam Map<String, Object> params) {
        PageUtils page = wareSkuService.queryPage(params);

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

WareSkuServiceImpl

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        /**
         * skuId: 1
         * wareId: 2
         */
        QueryWrapper<WareSkuEntity> queryWrapper = new QueryWrapper<>();
        String skuId = (String) params.get("skuId");
        if(!StringUtils.isEmpty(skuId)){
            queryWrapper.eq("sku_id",skuId);
        }
        String wareId = (String) params.get("wareId");
        if(!StringUtils.isEmpty(wareId)){
            queryWrapper.eq("ware_id",wareId);
        }
        IPage<WareSkuEntity> page = this.page(
                new Query<WareSkuEntity>().getPage(params),
                queryWrapper
        );
        return new PageUtils(page);
    }
http://localhost:88/api/ware/waresku/list
{
    "msg": "success",
    "code": 0,
    "page": {
        "totalCount": 2,
        "pageSize": 10,
        "totalPage": 1,
        "currPage": 1,
        "list": [
            {
                "id": 3,
                "skuId": 26,
                "wareId": 1,
                "stock": 100,
                "skuName": "测试 黑色",
                "stockLocked": 1
            }
        ]
    }
}

1.5、采购单维护

1.5.1、采购单维护-前端

采购需求:purchaseitem.vue




purchaseitem-add-or-update.vue




采购单:purchase.vue

 

purchase-add-or-update.vue




1.5.2、采购单维护-后端

1、查询采购需求

{
   page: 1,//当前页码
   limit: 10,//每页记录数
   sidx: 'id',//排序字段
   order: 'asc/desc',//排序方式
   key: '华为',//检索关键字
   status: 0,//状态    
   wareId: 1,//仓库id
}

PurchaseDetailController

    /**
     * 查询采购需求
     *
     * @param id
     * @return
     */
    @RequestMapping("/info/{id}")
    @RequiresPermissions("ware:purchasedetail:info")
    public R info(@PathVariable("id") Long id) {
        PurchaseDetailEntity purchaseDetail = purchaseDetailService.getById(id);

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

PurchaseDetailServiceImpl

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<PurchaseDetailEntity> queryWrapper = new QueryWrapper<>();

        //key: '华为',//检索关键字
        //status: 0,//状态
        //wareId: 1,//仓库id
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            queryWrapper.and(wrapper -> {
                wrapper.eq("purchase_id", key).or().eq("sku_id", key);
            });
        }
        String status = (String) params.get("status");
        if (!StringUtils.isEmpty(status) && !"0".equalsIgnoreCase(status)) {
            queryWrapper.eq("status", status);
        }
        String wareId = (String) params.get("wareId");
        if (!StringUtils.isEmpty(wareId) && !"0".equalsIgnoreCase(wareId)) {
            queryWrapper.eq("ware_id", wareId);
        }
        IPage<PurchaseDetailEntity> page = this.page(
                new Query<PurchaseDetailEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }
http://localhost:88/api/ware/purchasedetail/list
{
    "msg": "success",
    "code": 0,
    "page": {
        "totalCount": 1,
        "pageSize": 10,
        "totalPage": 1,
        "currPage": 1,
        "list": [
            {
                "id": 1,
                "purchaseId": 1,
                "skuId": 1,
                "skuNum": 1,
                "skuPrice": 1,
                "wareId": 1,
                "status": 1
            }
        ]
    }
}

2、查询未领取的采购单

PurchaseController

    /**
     * 查询未领取的采购单
     *
     * @param params
     * @return
     */
    @RequestMapping("/unreceive/list")
    @RequiresPermissions("ware:purchase:unreceive:list")
    public R unreceiveQuery(@RequestParam Map<String, Object> params) {
        PageUtils page = purchaseService.unreceiveQueryPage(params);

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

PurchaseServiceImpl

    @Override
    public PageUtils unreceiveQueryPage(Map<String, Object> params) {
        //查询新建状态和已分配状态
        QueryWrapper<PurchaseEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", PURCH_STATUS_CREATE.getCode()).or()
                .eq("status", PURCH_STATUS_ASSIGNED.getCode());
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            queryWrapper.and(w -> {
                w.eq("id", key).or().like("assignee_name", key);
            });
        }
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                queryWrapper
        );
        return new PageUtils(page);
    }
http://localhost:88/api/ware/purchase/unreceive/list
{
    "msg": "success",
    "code": 0,
    "page": {
        "totalCount": 1,
        "pageSize": 10,
        "totalPage": 1,
        "currPage": 1,
        "list": [
            {
                "id": 1,
                "assigneeId": 1,
                "assigneeName": "1",
                "phone": "10086",
                "priority": 1,
                "status": 1,
                "wareId": 1,
                "amount": 1,
                "createTime": "2022-01-27",
                "updateTime": "2022-01-27"
            }
        ]
    }
}

3、合并采购需求

{
  "purchaseId": 1, //整单id
  "items":[1,2,3,4] //合并项集合
}

MergeVo

package com.firefly.fireflymall.ware.vo;

import lombok.Data;

import java.util.List;

/**
 * @author Michale @EMail:[email protected]
 * @Date: 2022/1/27 11:01
 * @Name MergeVo
 * @Description:
 */
@Data
public class MergeVo {
    private Long purchaseId; //整单id
    private List<Long> items; //合并项集合
}

保存和更新时创建时间

package com.firefly.common.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @Author MyMetaObjectHandler
 * @Date: 2021/11/26 19:38
 * @Description:
 */
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
        this.setFieldValByName("status", 0, metaObject);
    
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime", new Date(), metaObject);

    }
}

PurchaseEntity

    @TableField(fill = FieldFill.INSERT)
    private Integer status;
    
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
   
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

创建采购状态枚举类

package com.firefly.common.constant;

/**
 * @author Michale @EMail:[email protected]
 * @Date: 2022/1/27 10:23
 * @Name WareContant
 * @Description:
 */
public class WareContant {
    public enum PurchStatusEnum {
        PURCH_STATUS_CREATE(0, "新建"),
        PURCH_STATUS_ASSIGNED(1, "已分配"),
        PURCH_STATUS_BUYING(2, "正在采购"),
        PURCH_STATUS_SUCCESS(3, "采购完成"),
        PURCH_STATUS_FAILED(4, "采购失败");
        private int code;
        private String msg;
        PurchStatusEnum(int code, String msg) {
            this.code = code;
            this.msg = msg;
        }
        public int getCode() {
            return code;
        }
        public String getMsg() {
            return msg;
        }
    }

    public enum PurchaseDetailStatusEnum {
        PURCHDATA_STATUS_CREATE(0, "新建"),
        PURCHDATA_STATUS_ASSIGNED(1, "已分配"),
        PURCHDATA_STATUS_BUYING(2, "正在采购"),
        PURCHDATA_STATUS_SUCCESS(3, "采购完成"),
        PURCHDATA_STATUS_FAILED(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;
        }
    }
}

PurchaseController

    /**
     * 合并采购需求
     *
     * @param mergeVo
     * @return
     */
    @PostMapping("/merge")
    @RequiresPermissions("ware:purchase:merge")
    public R mergePurchase(@RequestBody MergeVo mergeVo) {
        purchaseService.mergePurchase(mergeVo);
        return R.ok();
    }

PurchaseServiceImpl

@Override
    public void mergePurchase(MergeVo mergeVo) {
        Long purchaseId = mergeVo.getPurchaseId();
        if (purchaseId == null) {
            // 新建的采购单
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            this.save(purchaseEntity);
            Long purchaseEntityId = purchaseEntity.getId();
        } else {
            // 确认采购单状态为0或者1
            PurchaseEntity purchaseEntity = baseMapper.selectById(purchaseId);
            if (purchaseEntity.getStatus() != PURCH_STATUS_CREATE.getCode() || purchaseEntity.getStatus() != PURCH_STATUS_ASSIGNED.getCode()) {
                log.error(PURCHASE_STATUS_CANNOT);
                return;
            }
        }
        List<Long> items = mergeVo.getItems();
        Long finalPurchaseId = purchaseId;
        List<PurchaseDetailEntity> purchaseDetailEntityList = items.stream().map(item -> {
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
            purchaseDetailEntity.setId(item);
            purchaseDetailEntity.setPurchaseId(finalPurchaseId);
            purchaseDetailEntity.setStatus(PURCHDATA_STATUS_ASSIGNED.getCode());
            return purchaseDetailEntity;
        }).collect(Collectors.toList());
        boolean b = purchaseDetailService.saveBatch(purchaseDetailEntityList);
        if(!b){
            log.error(PURCHASE_CANNOT_MERGED);
        }
    }
http://localhost:88/api/ware/purchase/merge

4、领取采购单

[1,2,3,4]//采购单id

PurchaseController

    /**
     * 领取采购单
     *
     * @param ids
     * @return
     */
    @PostMapping("/receive")
    @RequiresPermissions("ware:purchase:receive")
    public R receivePurchase(@RequestParam List<Long> ids) {
        purchaseService.receivePurchase(ids);
        return R.ok();
    }

PurchaseServiceImpl

    @Override
    public void receivePurchase(List<Long> ids) {
        // 查询未分配或新建的采购单
        List<PurchaseEntity> collect = ids.stream().map(id -> {
            PurchaseEntity purchase = this.getById(id);
            return purchase;
        }).filter(item -> {
            Integer status = item.getStatus();
            if (status == PURCH_STATUS_CREATE.getCode() || status == PURCH_STATUS_ASSIGNED.getCode()) {
                return true;
            }
            return false;
        }).map(obj -> {
            //设置被领取采购单的状态
            obj.setStatus(PURCHDATA_STATUS_ASSIGNED.getCode());
            return obj;
        }).collect(Collectors.toList());
        this.updateBatchById(collect);
        // 改变采购项状态
        collect.forEach(item -> {
            Long id = item.getId();
            QueryWrapper<PurchaseDetailEntity> queryWrapper = new QueryWrapper<PurchaseDetailEntity>().eq("purchase_id", id);
            List<PurchaseDetailEntity> purchaseDetailEntities = purchaseDetailService.list(queryWrapper);
            List<PurchaseDetailEntity> detailEntityList = purchaseDetailEntities.stream().map(entity -> {
                PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
                purchaseDetailEntity.setId(entity.getId());
                purchaseDetailEntity.setStatus(PURCHDATA_STATUS_BUYING.getCode());
                return purchaseDetailEntity;
            }).collect(Collectors.toList());
            purchaseDetailService.updateBatchById(detailEntityList);
        });
    }

5、完成采购

{
   id: 123,//采购单id
   items: [{itemId:1,status:4,reason:""}]//完成/失败的需求详情
}

PurchaseController

    /**
     * 完成采购
     * @param purchaseDoneVo
     * @return
     */
    @PostMapping("/done")
    @RequiresPermissions("ware:purchase:deon")
    public R deon(@RequestBody PurchaseDoneVo purchaseDoneVo) {
        purchaseService.done(purchaseDoneVo);
        return R.ok();
    }

PurchaseServiceImpl

    @Transactional
    @Override
    public void done(PurchaseDoneVo purchaseDoneVo) {
        // 1、改变采购项的状态
        List<PurchaseItemVo> items = purchaseDoneVo.getItems();
        Boolean flag = true;
        List<PurchaseDetailEntity> updates = new ArrayList<>(10);
        for (PurchaseItemVo item : items) {
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
            if (item.getStatus() == PURCH_STATUS_FAILED.getCode()) {
                // 采购失败
                log.error(PURCHASE_BUYING_FAIL);
                flag = false;
                purchaseDetailEntity.setStatus(PURCH_STATUS_FAILED.getCode());
            } else {
                purchaseDetailEntity.setStatus(PURCH_STATUS_SUCCESS.getCode());
                // 3、将成功采购的入库
                PurchaseDetailEntity detailEntity = purchaseDetailService.getById(item.getItemId());
                wareSkuService.addStock(detailEntity.getSkuId(), detailEntity.getWareId(), detailEntity.getSkuNum());
            }
            purchaseDetailEntity.setId(item.getItemId());
            updates.add(purchaseDetailEntity);
        }
        purchaseDetailService.updateBatchById(updates);
        // 2、改变采购状态
        PurchaseEntity purchaseEntity = baseMapper.selectById(purchaseDoneVo.getId());
        purchaseEntity.setStatus(flag ? PURCH_STATUS_SUCCESS.getCode() : PURCH_STATUS_FAILED.getCode());
        purchaseEntity.setId(purchaseDoneVo.getId());
        baseMapper.updateById(purchaseEntity);
    }

WareSkuDao

    /**
     * 采购完成-入库
     *
     * @param skuId
     * @param wareId
     * @param skuNum
     */
    void addStock(@Param("skuId") Long skuId, @Param("wareId") Long wareId, @Param("skuNum") Integer skuNum);

WareSkuDao.xml

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

WareSkuServiceImpl

/**
     * 采购完成-入库
     *
     * @param skuId
     * @param wareId
     * @param skuNum
     */
    @Override
    public void addStock(Long skuId, Long wareId, Integer skuNum) {

        QueryWrapper<WareSkuEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sku_id", skuId).eq("ware_id", wareId);
        List<WareSkuEntity> wareSkuEntities = baseMapper.selectList(queryWrapper);

        if (wareSkuEntities != null && wareSkuEntities.size() > 0) {
            // 如果不是空的,添加库存
            baseMapper.addStock(skuId, wareId, skuNum);
        } else {
            // 保存新的
            WareSkuEntity wareSkuEntity = new WareSkuEntity();
            wareSkuEntity.setSkuId(skuId);
            wareSkuEntity.setWareId(wareId);
            wareSkuEntity.setStock(skuNum);
            wareSkuEntity.setStockLocked(0);
            try {
                // 远程查询sku名字
                R info = productFeignService.info(skuId);
                Map<String, Object> data = (Map<String, Object>) info.get("skuInfo");
                if (info.getCode() == 0) {
                    String skuName = (String) data.get("skuName");
                    wareSkuEntity.setSkuName(skuName);
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error(QUERY_SKUNAME_FAIL);
            }
            baseMapper.insert(wareSkuEntity);
        }
    }

分布式基础篇总结

AttrGroupController

84 pubsub、publish报错
解决如下:
1 npm install --save pubsub-js
2 在src下的main.js中引用:
import PubSub from 'pubsub-js'
Vue.prototype.PubSub = PubSub

85 数据库里少了value_type字段
解决如下:
在数据库的 pms_attr 表加上value_type字段,类型为tinyint就行;
在代码中,AttyEntity.java、AttrVo.java中各添加:private Integer valueType,
在AttrDao.xml中添加:<result property="valueType" column="value_type"/>

85 规格参数显示不出来页面,原因是要在每个分组属性上至少关联一个属性。控制台foreach报错null
解决如下:
在spuadd.vue的showBaseAttrs()方法中在 //先对表单的baseAttrs进行初始化加上非空判断 if (item.attrs != null)就可以了
          data.data.forEach(item => {
            let attrArray = [];
            if (item.attrs != null) {
              item.attrs.forEach(attr => {
              attrArray.push({
                attrId: attr.attrId,
                attrValues: "",
                showDesc: attr.showDesc
              });
            });
            }
            
            this.dataResp.baseAttrs.push(attrArray);
          });


92 feign超时异常导致读取失败
解决如下:
在gulimall-product的application.yml添加如下即可解决(时间设置长点就行了)
ribbon:
  ReadTimeout: 30000
  ConnectTimeout: 30000

100 点击规格找不到页面,以及规格回显问题解决
1 点击规格找不到页面,解决如下:
INSERT INTO sys_menu (menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (76, 37, '规格维护', 'product/attrupdate', '', 2, 'log', 0);

2 规格回显问题不出来
原因:
因为那个属性的值类型是多选而pms_product_attr_value这个表里面的属性值存的单个值。前端展示将这个值用;切割成数组来展示的。切完数组里面只有一个值就转成字符串。所以在多选下拉就赋不了值
解决如下:
将页面attrupdate.vue中showBaseAttrs这个方法里面的代码
if (v.length == 1) {
      v = v[0] +  ''
 }
换成下面这个
if (v.length == 1 && attr.valueType == 0) {
     v = v[0] + ''
}
1 分布式基附概念
微服务、注册中心、配置中心、远程调用、 Feign、网关

2 基础开发
springboot2.0 SpringCloud、 Mybatis-Plus、Vue组件化、阿里云对象存储

3 环境
Vmware、 Linux、 Docker、 MYSQL、 Redis、逆向工程&人人开源

4 开发规范
数据校验JSR303、全局异常处理、全局统一返回、全局跨域处理
枚举状态,业务状态码、VO与TO与PO划分,逻组删除

Lombok @Data  @Slf4j

下一章:day05-品牌管理
下一章:Elastic Search-全文检索
下一章:商城服务

你可能感兴趣的:(java,开发语言,后端)