Gulimall 分布式基础篇 -- 仓库管理

仓库管理

1. 整合ware服务&获取仓库列表

1.1 整合ware服务

首先 将ware配置nacos注册中心,将请求交给路由进行转发。

application.yml

server:
  port: 11000
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.56.105:3306/gulimall_wms?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: abc123
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
  application:
    name: gulimall-ware
mybatis-plus:
  mapper-locations: classpath:/mapper/**/*.xml
  global-config: # 全局配置
    db-config:
      id-type: auto # 主键自增
logging:
  level:
    com.atguigu.gulimall: debug

在nacos创建对应的命名空间ware,并配置到bootstrap.yml 上

bootstrap.yml

spring:
  application:
    name: gulimall-ware
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        namespace: acbe10b7-ca5a-4701-8003-5769754a5921

在GulimallWareApplication中添加注解实现注册发现功能

@EnableDiscoveryClient
@SpringBootApplication
public class GulimallWareApplication {

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

}

在Gulimall-gateway 中进行路由转发配置

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

1.2 获取仓库列表

在WareInfoController 中进行处理列表请求,添加搜索框功能

@RestController
@RequestMapping("ware/wareinfo")
public class WareInfoController {
    @Autowired
    private WareInfoService wareInfoService;

    /**
     * 列表
     */
    @RequestMapping("/list")
    //@RequiresPermissions("ware:wareinfo:list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = wareInfoService.queryPage(params);

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

}
public interface WareInfoService extends IService<WareInfoEntity> {

    PageUtils queryPage(Map<String, Object> params);
}
@Service("wareInfoService")
public class WareInfoServiceImpl extends ServiceImpl<WareInfoDao, WareInfoEntity> implements WareInfoService {

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<WareInfoEntity> wrapper = new QueryWrapper<>();
        String key = (String) 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. 查询库存&创建采购需求

2.1 查询库存

库存的数量应与采购是否成功有关,当采购成功,库存增加

@RestController
@RequestMapping("ware/waresku")
public class WareSkuController {
    @Autowired
    private WareSkuService wareSkuService;
 
    /**
     * 列表
     */
    @RequestMapping("/list")
    //@RequiresPermissions("ware:waresku:list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = wareSkuService.queryPage(params);
 
        return R.ok().put("page", page);
    }
}
public interface WareSkuService extends IService<WareSkuEntity> {
 
    PageUtils queryPage(Map<String, Object> params);
}
@Service("wareSkuService")
public class WareSkuServiceImpl extends ServiceImpl<WareSkuDao, WareSkuEntity> implements WareSkuService {
 
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        /**
         * skuId:
         * wareId:
         */
        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);
    }
 
}

 2.2 创建采购需求

@RestController
@RequestMapping("ware/purchasedetail")
public class PurchaseDetailController {
    @Autowired
    private PurchaseDetailService purchaseDetailService;
 
    /**
     * 列表
     */
    @RequestMapping("/list")
    //@RequiresPermissions("ware:purchasedetail:list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = purchaseDetailService.queryPage(params);
 
        return R.ok().put("page", page);
    }
}
public interface PurchaseDetailService extends IService<PurchaseDetailEntity> {
 
    PageUtils queryPage(Map<String, Object> params);
}
@Service("purchaseDetailService")
public class PurchaseDetailServiceImpl extends ServiceImpl<PurchaseDetailDao, PurchaseDetailEntity> implements PurchaseDetailService {
 
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        /**
         * key:
         * status:
         * wareId:
         */
        QueryWrapper<PurchaseDetailEntity> wrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        if(!StringUtils.isEmpty(key)){
            wrapper.and(w -> {
                w.eq("purchase_id",key).or().eq("sku_id",key);
            });
        }
        String status = (String) params.get("status");
        if(!StringUtils.isEmpty(status)){
            wrapper.eq("status",status);
        }
        String wareId = (String) 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);
    }
 
}

3. 合并采购需求

扫描二维码关注公众号,回复: 16933352 查看本文章

首先我们需要创建一个采购单,并关联管理员,我们可以在系统管理页面-->管理员列表进行创建

 

 采购单管理

 */
@RestController
@RequestMapping("ware/purchase")
public class PurchaseController {
    @Autowired
    private PurchaseService purchaseService;


//未被领取的采购单
        // /ware/purchase/unreceive/list
    @RequestMapping("/unreceive/list")
    public R unreceiveList(@RequestParam Map<String, Object> params){
        PageUtils page = purchaseService.queryPageUnreceivePurchase(params);

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

}
@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    //未被领取的采购单
    @Override
    public PageUtils queryPageUnreceivePurchase(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(      //对未被领取的采购单使用Wrapper进行存储,并使用分页插件进行展示数据
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>().eq("status",0).or().eq("status",1)
        );

        return new PageUtils(page);
    }
}

合并整单流程

当我们进行批量处理合并整单时,我们需要关联对应的采购单,采购单需要进行分配人员

1.采购需求中,合并到整单的请求url为/ware/purchase/merge,编写合并接口。
(1)如果不选择要合并的采购单即purchaseId=null,会创建新的采购单然后合并。
(2)采购单和采购需求的状态由枚举来区分,在公共模块gulimall-common定义库存常量类
WareConstant.java。
(3)合并到整单后,采购需求的状态由新建变为已分配。
 
2.修改采购单列表的日期显示以yyyy-MM-dd HH:mm:ss的格式显示,在application.yml中进行配置。
添加:
spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
完整yml配置如下:
server:
  port: 11000
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://xxxx:3306/gulimall_wms
    username: root
    password: root
  cloud:
    nacos:
      discovery:
        server-addr: xxxx:8848
  application:
    name: gulimall-ware
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
mybatis-plus:
  mapper-locations: classpath:/mapper/**/*.xml
  global-config: # 全局配置
    db-config:
      id-type: auto # 主键自增
logging:
  level:
    com.wen.gulimall: debug

在common模块的constant 创建Constant变量

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

合并整单

@RestController
@RequestMapping("ware/purchase")
public class PurchaseController {
    @Autowired
    private PurchaseService purchaseService;

  

//    合并整单
    // /ware/purchase/merge
    @PostMapping("/merge")
    public R mergePurchase(@RequestBody MergeVo mergeVo){
        purchaseService.mergePurchase(mergeVo);
        return R.ok();
    }
}
public interface PurchaseService extends IService<PurchaseEntity> {

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

    //未领取的采购单
    PageUtils queryPageUnreceivePurchase(Map<String, Object> params);

    //合并整单
    void mergePurchase(MergeVo mergeVo);
}
@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

    //未被领取的采购单
    @Override
    public PageUtils queryPageUnreceivePurchase(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(      //对未被领取的采购单使用Wrapper进行存储,并使用分页插件进行展示数据
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>().eq("status",0).or().eq("status",1)
        );

        return new PageUtils(page);
    }


    //合并整单的请求
//    首先当合并整单时,我们需要将两个采购需求分配到一个采购单中。并且采购单需要有一个分配人,我们需要在之前就要配置,并且创建相应的采购单
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void mergePurchase(MergeVo mergeVo) {
        Long purchaseId = mergeVo.getPurchaseId();    //采购整单Id,就是两个采购需求合并之后所创建的整单Id
        if(purchaseId == null){
            // 新建采购单
            PurchaseEntity purchaseEntity = new PurchaseEntity();   //采购单实体
            purchaseEntity.setCreateTime(new Date());   //添加创建整单日期
            purchaseEntity.setUpdateTime(new Date());   //更新时间
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());
            this.save(purchaseEntity);  //添加采购单实体
            purchaseId = purchaseEntity.getId();
        }
        // 采购需求ID
        List<Long> items = mergeVo.getItems();
        Long finalPurchaseId = purchaseId;   //采购需求页面中的采购单id
        List<PurchaseDetailEntity> collect = items.stream().map(i -> {
            PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();   //采购需求实体
            detailEntity.setId(i);
            detailEntity.setPurchaseId(finalPurchaseId);
            detailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode());   //采购需求被领取状态
            return detailEntity;  //返回采购需求实体
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(collect);  //批量修改采购需求实体

        PurchaseEntity purchaseEntity = new PurchaseEntity();  //采购单实体
        purchaseEntity.setUpdateTime(new Date());
        purchaseEntity.setId(purchaseId);
        this.updateById(purchaseEntity);
    }

}

4. 领取采购单 

@RestController
@RequestMapping("ware/purchase")
public class PurchaseController {
    @Autowired
    private PurchaseService purchaseService;

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

}
public interface PurchaseService extends IService<PurchaseEntity> {


    //领取采购单
    void receivedPurchase(List<Long> ids);
}
@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }


    /**
     * 领取采购单
     * @param ids 采购单id
     */
    @Override
    public void receivedPurchase(List<Long> ids) {

        List<PurchaseEntity> collect = ids.stream().map(id -> {
            PurchaseEntity byId = this.getById(id);
            return byId;
        }).filter(item -> {   // 1.确认当前采购单是新建或已分配状态
            if (item.getStatus() == WareConstant.PurchaseStatusEnum.CREATED.getCode() ||
                    item.getStatus() == WareConstant.PurchaseStatusEnum.ASSIGNED.getCode()) {
                return true;
            }
            return false;
        }).map(item -> {   //item 改变状态为被领取
            item.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getCode());
            item.setUpdateTime(new Date()); //更新时间
            return item;
        }).collect(Collectors.toList());
        // 2. 改变采购单的状态
        this.updateBatchById(collect);
        // 3. 改变采购项(需求)的状态
        collect.forEach(item -> {
            List<PurchaseDetailEntity> entities = purchaseDetailService.listDetailByPurchaseId(item.getId());
            List<PurchaseDetailEntity> detailEntities = entities.stream().map(entity -> {
                PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
                detailEntity.setId(entity.getId());
                detailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.BUYING.getCode());
                return detailEntity;
            }).collect(Collectors.toList());
            purchaseDetailService.updateBatchById(detailEntities);
        });
    }
}

当采购单被领取时,对应的采购需求也要改变状态。

public interface PurchaseDetailService extends IService<PurchaseDetailEntity> {

    //采购需求列表
    PageUtils queryPage(Map<String, Object> params);

    //改变采购需求的状态
    List<PurchaseDetailEntity> listDetailByPurchaseId(Long id);
}
@Service("purchaseDetailService")
public class PurchaseDetailServiceImpl extends ServiceImpl<PurchaseDetailDao, PurchaseDetailEntity> implements PurchaseDetailService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    //通过采购单id获取采购需求id
    @Override
    public List<PurchaseDetailEntity> listDetailByPurchaseId(Long id) {
//        PurchaseDetailEntity purchaseDetailEntity=purchaseDetailService.getById(id);

//        item.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getCode());
//        item.setUpdateTime(new Date()); //更新时间
        List<PurchaseDetailEntity> purchaseId = this.list(new QueryWrapper<PurchaseDetailEntity>().eq("purchase_id", id));
        //this关键字的意义被解释为“指向当前对象的引用”,就是当前purchaseId的引用

//        new QueryWrapper<PurchaseDetailEntity>().eq("purchase_id", id)

//        querywrapper用法: 继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件
//        及 LambdaQueryWrapper, 可以通过 new QueryWrapper().lambda() 方法获取.

//        lamnda表达式:
        //        方法示例:
//        eq:等于,ne:不等于
//                or()  或者
//                like()  模糊查询

//            代码示例:
//        @SpringBootTest
//        class MybatisplusShiroApplicationTests {
//
//            @Autowired
//            private UserMapper userMapper;
//
//            @Test
//            void contextLoads() {
//
//                QueryWrapper<User> wrapper = new QueryWrapper<>();     //将需要查询的表放到    queryWrapper<>中
//                //第一个参数为表列名,第二个为你的条件
//                wrapper.eq("username", "zhangsan");
//                User user = userMapper.selectOne(wrapper);
//                System.out.println(user);
//
//            }
//        }

//        表示采购需求中通过采购单id获取采购需求id
        //此处this是代表了IServcie ,list方法是IService中的,而每个service方法又都继承IService
        return purchaseId;
    }

}

5. 完成采购

提示:改变采购项的状态
(1)采购项有可能不是全量失败,数据库表wms_purchase_detail应有应该采购的数量和已采购的数量
以及采购失败的原因字段,后面可以完善。
 
完成采购项:
(1)请求url为/ware/purchase/done,
(2)请求参数,如下:
{
   id: 123,//采购单id
   items: [{itemId:1,status:4,reason:""}]//完成/失败的需求详情
}
(3)业务流程
改变采购项的状态-》将成功采购的进行入库(如果没有这个商品的库存记录新增,有则修改库存)-》
改变采购单的状态。
注意:采购项完全采购成功,采购单的状态才是已完成;若采购项没有完全采购成功,采购的状态是有异常。
(4)测试
    1)采购单有异常
    2)采购单已完成
注意观察成功的采购项即已完成的采购项对应商品库存的变化。

创建专属VO

@Data
public class PurchaseDoneVo {

    private Long id;

    private List<PurchaseItemDoneVo> items;


}
@Data
public class PurchaseItemDoneVo {

    private Long itemId; //采购项id

    private Integer status;   //采购项状态

    private String reason;

}
@RestController
@RequestMapping("ware/purchase")
public class PurchaseController {
    @Autowired
    private PurchaseService purchaseService;



    @PostMapping("/done")
    public R finishPurchase(@RequestBody PurchaseDoneVo doneVo){
        purchaseService.done(doneVo);

        return R.ok();
    }
}
public interface PurchaseService extends IService<PurchaseEntity> {


    //完成采购
    void done(PurchaseDoneVo doneVo);
}
@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Autowired
    private WareSkuService wareSkuService;

//    完成采购
    @Override
    public void done(PurchaseDoneVo doneVo) {

        Long id = doneVo.getId();
        // 1. 改变采购项的状态
        Boolean flag = true;

        List<PurchaseItemDoneVo> items = doneVo.getItems();

        List<PurchaseDetailEntity> updates = new ArrayList<>();
        //遍历采购需求
        for (PurchaseItemDoneVo item:items){
            //新建一个采购需求实体
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();

            if (item.getStatus()==WareConstant.PurchaseStatusEnum.HASERROR.getCode()){
                flag=false;
                purchaseDetailEntity.setStatus(item.getStatus());
            }else {
                //将采购项状态变为已完成
                purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.FINISH.getCode());

                // 并查询采购需求的详细信息
                //当获取这些信息后,将交给wareSkuService 进行处理·
                PurchaseDetailEntity entity = purchaseDetailService.getById(item.getItemId());
                //添加新的方法
                //将成功采购的进行入库
                wareSkuService.addStock(entity.getSkuId(), entity.getWareId(), entity.getSkuNum());
            }
            //获取采购需求id
            purchaseDetailEntity.setId(item.getItemId());

            //更新采购需求
            updates.add(purchaseDetailEntity);

        }
        // 批量更新采购项
        purchaseDetailService.updateBatchById(updates);


//      改变采购单状态
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(id);
        purchaseEntity.setStatus(flag?WareConstant.PurchaseStatusEnum.FINISH.getCode():WareConstant.PurchaseStatusEnum.HASERROR.getCode());
        purchaseEntity.setUpdateTime(new Date());

        this.updateById(purchaseEntity);

    }
}
public interface WareSkuService extends IService<WareSkuEntity> {

    //查询商品库存数据
    PageUtils queryPage(Map<String, Object> params);

    //将采购完成的采购需求进行入库
    void addStock(Long skuId, Long wareId, Integer skuNum);
}

@Service("wareSkuService")
public class WareSkuServiceImpl extends ServiceImpl<WareSkuDao, WareSkuEntity> implements WareSkuService {

    @Resource
    private ProductFeignService productFeignService;


    //将采购需求完成的进行入库
    @Override
    public void addStock(Long skuId, Long wareId, Integer skuNum) {

        // 1. 判断如果没有这个商品的库存记录新增,有则修改库存
        List<WareSkuEntity> entities  = this.baseMapper.selectList(new QueryWrapper<WareSkuEntity>().eq("sku_id", skuId).eq("ware_id", wareId));

        if (entities==null || entities.size()==0){
            WareSkuEntity entity = new WareSkuEntity();
            //新增库存
            try {
                R info = productFeignService.info(skuId);
                Map<String,Object> skuInfo = (Map<String, Object>) info.get("skuInfo");
                entity.setSkuName((String) skuInfo.get("skuName"));
            } catch (Exception e) {

            }
            this.baseMapper.insert(entity);
        }else {
            //创建更新库存数目的方法dao
            this.baseMapper.updateStock(skuId,wareId,skuNum);
        }
    }

}
@Mapper
public interface WareSkuDao extends BaseMapper<WareSkuEntity> {
 
    void updateStock(@Param("skuId") Long skuId, @Param("wareId") Long wareId, @Param("skuNum") Integer skuNum);
 
}
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<mapper namespace="com.wen.gulimall.ware.dao.WareSkuDao">
 
	<!-- 可根据自己的需求,是否要使用 -->
    <resultMap type="com.wen.gulimall.ware.entity.WareSkuEntity" id="wareSkuMap">
        <result property="id" column="id"/>
        <result property="skuId" column="sku_id"/>
        <result property="wareId" column="ware_id"/>
        <result property="stock" column="stock"/>
        <result property="skuName" column="sku_name"/>
        <result property="stockLocked" column="stock_locked"/>
    </resultMap>
    <update id="updateStock">
        UPDATE wms_ware_sku SET stock = stock + #{skuNum} WHERE sku_id = #{skuId} AND ware_id = #{wareId}
    </update>
 
 
</mapper>
采购单和采购需求的分页没有起作用,添加分页配置WareMybatisPlusConfig,将开启事务注解和
Mapper层扫描注解由启动类上放到分页配置类上如下:
@EnableTransactionManagement // 开启事务
@MapperScan("com.atguigu.gulimall.ware.dao")
@Configuration
public class WareMybatisPlusConfig {
    /**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
     */
    @Bean
    public PaginationInterceptor mybatisPlusInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        //设置请求的页面大于最大页后操作,true调回首页,false 继续请求,默认false。
        paginationInterceptor.setOverflow(true);
        //设置最大单页限制数量,默认500条
        paginationInterceptor.setLimit(1000);
        return paginationInterceptor;
    }
}
@FeignClient("gulimall-product")
public interface ProductFeignService {

    /**
     *
     * 调用微服务由两种方式
     * 1. 全部请求通过路由进行转发,则Feign注解为@FeignClient("gulimall-gateway")
     *     服务请求路径为api/product/skuinfo/info/{skuId}
     *
     * 2. 直接调用product服务  ,则feign注解为 @FeignClient("gulimall-product")
     *     服务请求为/product/skuinfo/info/{skuId}
     *
     *
     * @param skuId
     * @return
     */

    //通过商品skuId获取商品skuName
    @RequestMapping("/product/skuinfo/info/{skuId}")
    public R info(@PathVariable("skuId") Long skuId);

}
@Service("wareSkuService")
public class WareSkuServiceImpl extends ServiceImpl<WareSkuDao, WareSkuEntity> implements WareSkuService {
 
    @Resource
    private ProductFeignService productFeignService;
    
    ...
 
    /**
     * 添加库存
     * @param skuId
     * @param wareId
     * @param skuNum
     */
    @Override
    public void addStock(Long skuId, Long wareId, Integer skuNum) {
        // 1. 判断如果没有这个商品的库存记录新增,有则修改库存
        List<WareSkuEntity> entities = this.baseMapper.selectList(new QueryWrapper<WareSkuEntity>().eq("sku_id", skuId).eq("ware_id", wareId));
        if(entities == null || entities.size() == 0){
            // 新增库存
            WareSkuEntity wareSkuEntity = new WareSkuEntity();
            wareSkuEntity.setSkuId(skuId);
            wareSkuEntity.setWareId(wareId);
            wareSkuEntity.setStock(skuNum);
            wareSkuEntity.setStockLocked(0);
            // todo 远程查询sku的名称,如果失败,整个事务无需回滚
            // 事务不回滚:1. 自己catch异常
            // 2. todo 还有什么方法让异常出现以后不会滚,高级篇
            try {
                R info = productFeignService.info(skuId);
                Map<String,Object> skuInfo = (Map<String, Object>) info.get("skuInfo");
                wareSkuEntity.setSkuName((String) skuInfo.get("skuName"));
            } catch (Exception e) {
 
            }
            this.baseMapper.insert(wareSkuEntity);
        }else {
            // 更新库存
            this.baseMapper.updateStock(skuId,wareId,skuNum);
        }
 
    }
 
}

6. 商品管理--spu规格维护

获取spu规格:
商品系统-》商品维护-》spu管理-》点击spu管理页面列表的规格,规格参数要回显。
(1)规格参数回显的请求url为/product/attr/base/listforspu/4
@RestController
@RequestMapping("product/attr")
public class AttrController {
    @Autowired
    private AttrService attrService;
    @Resource
    private ProductAttrValueService productAttrValueService;
 
    ///product/attr/base/listforspu/{spuId}
    @GetMapping("/base/listforspu/{spuId}")
    public R baseAttrListForSpu(@PathVariable("spuId") Long spuId){
        List<ProductAttrValueEntity> entities = productAttrValueService.baseAttrListForSpu(spuId);
        return R.ok().put("data",entities);
    }
}
public interface ProductAttrValueService extends IService<ProductAttrValueEntity> {
 
    ...
 
    List<ProductAttrValueEntity> baseAttrListForSpu(Long spuId);
 
    ...
}
@Service("productAttrValueService")
public class ProductAttrValueServiceImpl extends ServiceImpl<ProductAttrValueDao, ProductAttrValueEntity> implements ProductAttrValueService {
 
    ...
 
    @Override
    public List<ProductAttrValueEntity> baseAttrListForSpu(Long spuId) {
        List<ProductAttrValueEntity> entities = this.baseMapper.selectList(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));
        return entities;
    }
}
修改商品规格:
商品系统-》商品维护-》spu管理-》点击spu管理页面列表的规格=》修改规格维护页面的数据
=》点击确认修改。
(1)修改商品规格的请求url为/product/attr/update/{spuId}
@RestController
@RequestMapping("product/attr")
public class AttrController {
    @Autowired
    private AttrService attrService;
    @Resource
    private ProductAttrValueService productAttrValueService;
 
    ...
 
    ///product/attr/update/{spuId}
    @PostMapping("/update/{spuId}")
    public R updateSpuAttr(@PathVariable("spuId") Long spuId,
                           @RequestBody List<ProductAttrValueEntity> entities){
        productAttrValueService.updateSpuAttr(spuId,entities);
        return R.ok();
    }
}
public interface ProductAttrValueService extends IService<ProductAttrValueEntity> {
 
    ...
 
    void updateSpuAttr(Long spuId, List<ProductAttrValueEntity> entities);
}
@Service("productAttrValueService")
public class ProductAttrValueServiceImpl extends ServiceImpl<ProductAttrValueDao, ProductAttrValueEntity> implements ProductAttrValueService {
 
    ...
 
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateSpuAttr(Long spuId, List<ProductAttrValueEntity> entities) {
        //1. 删除这个spuId之前对应的所有属性
        this.baseMapper.delete(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id",spuId));
        //2. 新增修改后的
        List<ProductAttrValueEntity> collect = entities.stream().map(item -> {
            item.setSpuId(spuId);
            return item;
        }).collect(Collectors.toList());
        this.saveBatch(collect);
    }
 
}

分布式基础篇总结

1、分页请求参数 - 谷粒商城 - 易文档 (easydoc.net)

猜你喜欢

转载自blog.csdn.net/weixin_55347789/article/details/133273703