最后来编写完成采购单的请求,采购人员领取到采购单之后实施采购,完成之后提交到系统,对应的API文档:
07、完成采购
POST
/ware/purchase/done
请求参数
{
id: 123,//采购单id
items: [{itemId:1,status:4,reason:""}]//完成/失败的需求详情
}
响应数据
{
"msg": "success",
"code": 0
}
postman模拟场景:
注意出现{“msg”:“invalid token”,“code”:401}是因为请求没有加token验证,需要到前端查一下token的值添加进去即可
找到前端的正常请求的请求头;
之后将token输入到postman中即可,可以看到正常响应404:
之后编写这个接口,先来到controller:
/**
* 完成采购单发出的请求
* @param doneVo
* @return
*/
///ware/purchase/done
@PostMapping("/done")
public R finish(@RequestBody PurchaseDoneVo doneVo){
purchaseService.done(doneVo);
return R.ok();
}
此处需要引入PurchaseDoneVo和PurchaseItemDoneVo来保存请求信息:
package com.atguigu.gulimall.ware.vo;
import lombok.Data;
@Data
public class PurchaseItemDoneVo {
//{itemId:1,status:4,reason:""}
private Long itemId;
private Integer status;
private String reason;
}
package com.lastingwar.mall.ware.vo;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
public class PurchaseDoneVo {
@NotNull
private Long id;//采购单id
private List<PurchaseItemDoneVo> items;
}
之后创建和实现方法done(doneVo):
package com.lastingwar.mall.ware.service.impl;
import com.lastingwar.common.constant.WareConstant;
import com.lastingwar.mall.ware.entity.PurchaseDetailEntity;
import com.lastingwar.mall.ware.service.PurchaseDetailService;
import com.lastingwar.mall.ware.service.WareSkuService;
import com.lastingwar.mall.ware.vo.MergeVo;
import com.lastingwar.mall.ware.vo.PurchaseDoneVo;
import com.lastingwar.mall.ware.vo.PurchaseItemDoneVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lastingwar.common.utils.PageUtils;
import com.lastingwar.common.utils.Query;
import com.lastingwar.mall.ware.dao.PurchaseDao;
import com.lastingwar.mall.ware.entity.PurchaseEntity;
import com.lastingwar.mall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;
@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {
@Autowired
WareSkuService wareSkuService;
@Autowired
PurchaseDetailService detailService;
@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 params
* @return
*/
@Override
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);
}
/**
* 合并采购单的方法
* @param mergeVo 采购单ID
*/
@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);
}
/**
*
* @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);
});
}
@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);
}
}
之后需要添加一个入库的操作:
package com.lastingwar.mall.ware.service.impl;
import com.lastingwar.common.utils.R;
import com.lastingwar.mall.ware.feign.ProductFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lastingwar.common.utils.PageUtils;
import com.lastingwar.common.utils.Query;
import com.lastingwar.mall.ware.dao.WareSkuDao;
import com.lastingwar.mall.ware.entity.WareSkuEntity;
import com.lastingwar.mall.ware.service.WareSkuService;
import org.springframework.util.StringUtils;
@Service("wareSkuService")
public class WareSkuServiceImpl extends ServiceImpl<WareSkuDao, WareSkuEntity> implements WareSkuService {
@Autowired
WareSkuDao wareSkuDao;
@Autowired
ProductFeignService productFeignService;
/**
* 查询对应仓库ID中商品的信息
* @param params 请求信息
* @return
*/
@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);
}
@Override
public void addStock(Long skuId, Long wareId, Integer skuNum) {
//1、判断如果还没有这个库存记录新增
List<WareSkuEntity> entities = wareSkuDao.selectList(new QueryWrapper<WareSkuEntity>().eq("sku_id", skuId).eq("ware_id", wareId));
if(entities == null || entities.size() == 0){
WareSkuEntity skuEntity = new WareSkuEntity();
skuEntity.setSkuId(skuId);
skuEntity.setStock(skuNum);
skuEntity.setWareId(wareId);
skuEntity.setStockLocked(0);
//TODO 远程查询sku的名字,如果失败,整个事务无需回滚
//1、自己catch异常
//TODO 还可以用什么办法让异常出现以后不回滚?高级
try {
R info = productFeignService.info(skuId);
Map<String,Object> data = (Map<String, Object>) info.get("skuInfo");
if(info.getCode() == 0){
skuEntity.setSkuName((String) data.get("skuName"));
}
}catch (Exception e){
}
wareSkuDao.insert(skuEntity);
}else{
wareSkuDao.addStock(skuId,wareId,skuNum);
}
}
}
商品入库需要远程调用商品服务来检索商品的详细信息,添加一个远程调用接口:
package com.lastingwar.mall.ware.feign;
import com.lastingwar.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient("mall-product")
public interface ProductFeignService {
/**
* /product/skuinfo/info/{skuId}
*
*
* 1)、让所有请求过网关;
* 1、@FeignClient("mall-gateway"):给mall-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);
}
同时在主程序开启远程调用:
package com.lastingwar.mall.ware;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class MallWareApplication {
public static void main(String[] args) {
SpringApplication.run(MallWareApplication.class, args);
}
}
最后在关联表中保存信息的方法wareSkuDao.addStock(skuId,wareId,skuNum);
package com.lastingwar.mall.ware.dao;
import com.lastingwar.mall.ware.entity.WareSkuEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 商品库存
*
* @author yhm
* @email [email protected]
* @date 2020-05-29 17:05:21
*/
@Mapper
public interface WareSkuDao extends BaseMapper<WareSkuEntity> {
void addStock(@Param("skuId") Long skuId, @Param("wareId") Long wareId, @Param("skuNum") Integer skuNum);
}
在xml中添加对应的sql语句:
<?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.lastingwar.mall.ware.dao.WareSkuDao">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.lastingwar.mall.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>