库存系统
整合ware服务
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
application:
name: gulimall-ware
-
主启动:
-
@EnableDiscoveryClient
-
@MapperScan("com.wlq.gulimall.ware.dao")
-
@EnableTransactionManagement
-
配置网关
- id: ware_route
uri: lb://gulimall-ware
predicates:
- Path=/api/ware/**
filters:
- RewritePath=/api/(?<segment>.*),/$\{segment}
- 配置分页插件:com.wlq.gulimall.ware.config.WareMyBatisConfig
@EnableTransactionManagement
@MapperScan("com.atguigu.gulimall.ware.dao")
@Configuration
public class WareMyBatisConfig {
//引入分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(true);
// // 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(1000);
return paginationInterceptor;
}
}
- 启动ware服务
1、仓库维护
-
测试仓库维护的新增、删除、修改功能
-
修改WareInfoServiceImpl,增加模糊检索功能
@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);
}
- 测试
2、商品库存
- /ware/waresku/list
1、查询修改
- 修改它的实现方法: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);
}
- 测试
3、采购单维护
1、给库存添加商品应该是从采购单进行添加
商品库存里的新增只是为了测试方便
2、新建一个采购需求
2、完善采购需求的模糊检索
- /ware/purchasedetail/list
- 修改PurchaseDetailServiceImpl
@Override
public PageUtils queryPage(Map<String, Object> params) {
/**
* status: 0,//状态
* wareId: 1,//仓库id
*/
QueryWrapper<PurchaseDetailEntity> queryWrapper = new QueryWrapper<PurchaseDetailEntity>();
String key = (String) params.get("key");
if(!StringUtils.isEmpty(key)){
//purchase_id sku_id
queryWrapper.and(w->{
w.eq("purchase_id",key).or().eq("sku_id",key);
});
}
String status = (String) params.get("status");
if(!StringUtils.isEmpty(status)){
//purchase_id sku_id
queryWrapper.eq("status",status);
}
String wareId = (String) params.get("wareId");
if(!StringUtils.isEmpty(wareId)){
//purchase_id sku_id
queryWrapper.eq("ware_id",wareId);
}
IPage<PurchaseDetailEntity> page = this.page(
new Query<PurchaseDetailEntity>().getPage(params),
queryWrapper
);
return new PageUtils(page);
}
- 测试
3、合并采购需求
1、新增采购单
分配一个采购人员
2、查询未领取的采购单
-
/ware/purchase/unreceive/list
-
PurchaseController
/**
* 查询未领取的采购单
*/
@RequestMapping("/unreceive/list")
//@RequiresPermissions("ware:purchase:list")
public R unreceivelist(@RequestParam Map<String, Object> params){
PageUtils page = purchaseService.queryPageUnreceivePurchase(params);
return R.ok().put("page", page);
}
- service
PageUtils queryPageUnreceivePurchase(Map<String, Object> params);
- impl
public PageUtils queryPageUnreceivePurchase(Map<String, Object> params) {
IPage<PurchaseEntity> page = this.page(
new Query<PurchaseEntity>().getPage(params),
new QueryWrapper<PurchaseEntity>().eq("status",0).or().eq("status",1)
);
return new PageUtils(page);
}
- 测试
3、合并采购需求
- /ware/purchase/merge
- 新建VO:com.wlq.gulimall.ware.vo.MergeVo
@Data
public class MergeVo {
/**
* purchaseId //整单id
* items //[1,2,3,4] 合并项集合
*/
private Long purchaseId;
private List<Long> items;
}
- PurchaseController
/**
* 合并采购需求
* @param mergeVo
* @return
*/
///ware/purchase/merge
@PostMapping("/merge")
public R merge(@RequestBody MergeVo mergeVo){
purchaseService.mergePurchase(mergeVo);
return R.ok();
}
- service
void mergePurchase(MergeVo mergeVo);
- common下新建:com.wlq.common.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;
}
}
}
- impl
@Transactional
@Override
public void mergePurchase(MergeVo mergeVo) {
Long purchaseId = mergeVo.getPurchaseId();
if(purchaseId == null){
//1、新建一个
PurchaseEntity purchaseEntity = new PurchaseEntity();
purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());
purchaseEntity.setCreateTime(new Date());
purchaseEntity.setUpdateTime(new Date());
this.save(purchaseEntity);
purchaseId = purchaseEntity.getId();
}
//TODO 确认采购单状态是0,1才可以合并
List<Long> items = mergeVo.getItems();
Long finalPurchaseId = purchaseId;
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());
detailService.updateBatchById(collect);
PurchaseEntity purchaseEntity = new PurchaseEntity();
purchaseEntity.setId(purchaseId);
purchaseEntity.setUpdateTime(new Date());
this.updateById(purchaseEntity);
}
- 测试合并整单
- 对比未合单之前
4、领取采购单
postman模拟手机接单,领取采购单
-
/ware/purchase/received
-
PurchaseController
/**
* 领取采购单
* @return
*/
@PostMapping("/received")
public R received(@RequestBody List<Long> ids){
purchaseService.received(ids);
return R.ok();
}
- service
void received(List<Long> ids);
- impl
/**
*
* @param ids 采购单id
*/
@Override
public void received(List<Long> ids) {
//1、确认当前采购单是新建或者已分配状态
List<PurchaseEntity> collect = ids.stream().map(id -> {
PurchaseEntity byId = this.getById(id);
return byId;
}).filter(item -> {
if (item.getStatus() == WareConstant.PurchaseStatusEnum.CREATED.getCode() ||
item.getStatus() == WareConstant.PurchaseStatusEnum.ASSIGNED.getCode()) {
return true;
}
return false;
}).map(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 = detailService.listDetailByPurchaseId(item.getId());
List<PurchaseDetailEntity> detailEntities = entities.stream().map(entity -> {
PurchaseDetailEntity entity1 = new PurchaseDetailEntity();
entity1.setId(entity.getId());
entity1.setStatus(WareConstant.PurchaseDetailStatusEnum.BUYING.getCode());
return entity1;
}).collect(Collectors.toList());
detailService.updateBatchById(detailEntities);
});
}
- listDetailByPurchaseId 方法实现
- service
List<PurchaseDetailEntity> listDetailByPurchaseId(Long id);
- impl : PurchaseDetailServiceImpl
@Override
public List<PurchaseDetailEntity> listDetailByPurchaseId(Long id) {
List<PurchaseDetailEntity> purchaseId = this.list(new QueryWrapper<PurchaseDetailEntity>().eq("purchase_id", id));
return purchaseId;
}
postman模拟领取采购单
-
方送请求
-
查看采购需求,采购单
5、完成采购
-
/ware/purchase/done
-
新建Vo
-
PurchaseDoneVo
@Data
public class PurchaseDoneVo {
@NotNull
private Long id;//采购单id
private List<PurchaseItemDoneVo> items;
}
- PurchaseItemDoneVo
@Data
public class PurchaseItemDoneVo {
//{itemId:1,status:4,reason:""}
private Long itemId;
private Integer status;
private String reason;
}
- PurchaseController
/**
* 完成采购单
*/
///ware/purchase/done
@PostMapping("/done")
public R finish(@RequestBody PurchaseDoneVo doneVo){
purchaseService.done(doneVo);
return R.ok();
}
- service
void done(PurchaseDoneVo doneVo);
- impl
@Transactional
@Override
public void done(PurchaseDoneVo doneVo) {
Long id = doneVo.getId();
//2、改变采购项的状态
Boolean flag = true;
List<PurchaseItemDoneVo> items = doneVo.getItems();
List<PurchaseDetailEntity> updates = new ArrayList<>();
for (PurchaseItemDoneVo item : items) {
PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
if(item.getStatus() == WareConstant.PurchaseDetailStatusEnum.HASERROR.getCode()){
flag = false;
detailEntity.setStatus(item.getStatus());
}else{
detailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.FINISH.getCode());
3、将成功采购的进行入库
PurchaseDetailEntity entity = detailService.getById(item.getItemId());
wareSkuService.addStock(entity.getSkuId(),entity.getWareId(),entity.getSkuNum());
}
detailEntity.setId(item.getItemId());
updates.add(detailEntity);
}
detailService.updateBatchById(updates);
//1、改变采购单状态
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);
}
addStock方法实现
- service
void addStock(Long skuId, Long wareId, Integer skuNum);
- impl
@Autowired
WareSkuDao wareSkuDao;
- WareSkuDao
@Mapper
public interface WareSkuDao extends BaseMapper<WareSkuEntity> {
void addStock(@Param("skuId") Long skuId, @Param("wareId") Long wareId, @Param("skuNum") Integer skuNum);
}
- xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wlq.gulimall.ware.dao.WareSkuDao">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.wlq.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="addStock">
UPDATE `wms_ware_sku` SET stock=stock+#{skuNum} WHERE sku_id=#{skuId} AND ware_id=#{wareId}
</update>
</mapper>
- ProductFeignService
@FeignClient("gulimall-product")
public interface ProductFeignService {
/**
* /product/skuinfo/info/{skuId}
*
*
* 1)、让所有请求过网关;
* 1、@FeignClient("gulimall-gateway"):给gulimall-gateway所在的机器发请求
* 2、/api/product/skuinfo/info/{skuId}
* 2)、直接让后台指定服务处理
* 1、@FeignClient("gulimall-gateway")
* 2、/product/skuinfo/info/{skuId}
*
* @return
*/
@RequestMapping("/product/skuinfo/info/{skuId}")
public R info(@PathVariable("skuId") Long skuId);
}
- 主启动
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.wlq.gulimall.ware.feign")
@MapperScan("com.wlq.gulimall.ware.dao")
public class GulimallWareApplication {
public static void main(String[] args) {
SpringApplication.run(GulimallWareApplication.class, args);
}
}
- postman测试
4、完善商品管理的spu规格维护
1、获取spu规格,并回显
- /product/attr/base/listforspu/{spuId}
如果点击规格出现404
/src/router/index.js 在mainRoutes->children【】里面加上这个就不会404了:{ path: ‘/product-attrupdate’, component: _import(‘modules/product/attrupdate’), name: ‘attr-update’, meta: { title: ‘规格维护’, isTab: true } }
- 修改product服务的AttrController
/**
* 获取spu规格
* @param spuId
* @return
*/
// /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);
}
- ProductAttrValueService
List<ProductAttrValueEntity> baseAttrlistforspu(Long spuId);
- impl
@Override
public List<ProductAttrValueEntity> baseAttrlistforspu(Long spuId) {
List<ProductAttrValueEntity> entities = this.baseMapper.selectList(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));
return entities;
}
- 测试
2、修改参数的保存方法(添加批量保存方法)
- AttrController
/**
* 批量保存
*/
///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();
}
- ProductAttrValueService
void updateSpuAttr(Long spuId, List<ProductAttrValueEntity> entities);
- impl
@Transactional
@Override
public void updateSpuAttr(Long spuId, List<ProductAttrValueEntity> entities) {
//1、删除这个spuId之前对应的所有属性
this.baseMapper.delete(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id",spuId));
List<ProductAttrValueEntity> collect = entities.stream().map(item -> {
item.setSpuId(spuId);
return item;
}).collect(Collectors.toList());
this.saveBatch(collect);
}
- 测试
确定修改后查看,回显修改后的数据成功
分布式基础篇总结
- 1、分布式基础概念
- 微服务、注册中心、配置中心、远程调用、Feign、 网关
- 2、基础开发
- SpringBoot2.0、 SpringCloud、 Mybatis-Plus、 Vue组件化、阿里云对象存储
- 3、环境
- Vagrant、 Linux、 Docker、 MySQL、 Redis、 逆向工程&人人开源
- 4、开发规范
- 数据校验JSR303、全局异常处理、全局统一返回、全局跨域处理
- 枚举状态、业务状态码、VO与TO与PO划分、逻辑删除
- Lombok: @Data、 @SIf4j