库存预警功能
This commit is contained in:
parent
a9802710ef
commit
a962939db8
@ -63,7 +63,16 @@ CREATE TABLE `li_order_package_item` (
|
|||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin ROW_FORMAT=DYNAMIC;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
/*
|
||||||
|
订单货物增加发货数量
|
||||||
|
*/
|
||||||
ALTER TABLE li_order_item ADD `deliver_number` int DEFAULT NULL COMMENT '发货数量';
|
ALTER TABLE li_order_item ADD `deliver_number` int DEFAULT NULL COMMENT '发货数量';
|
||||||
|
|
||||||
ALTER TABLE li_goods_sku ADD `alert_quantity` int DEFAULT NULL COMMENT '预警库存';
|
/*
|
||||||
|
sku增加预警库存
|
||||||
|
*/
|
||||||
|
ALTER TABLE li_goods_sku ADD `alert_quantity` int DEFAULT NULL COMMENT '预警库存';
|
||||||
|
/*
|
||||||
|
增加库存预警菜单
|
||||||
|
*/
|
||||||
|
INSERT INTO `lilishop`.`li_store_menu`(`id`, `create_by`, `create_time`, `delete_flag`, `update_by`, `update_time`, `description`, `front_route`, `icon`, `level`, `name`, `parent_id`, `path`, `sort_order`, `title`, `permission`) VALUES (1349237928434098177, NULL, '2022-01-11 22:35:45.000000', b'0', NULL, '2022-01-11 22:37:05', NULL, 'goods/goods-seller/alertQuantity', 'ios-american-football', 2, 'alert-goods-quantity', '1348810864748945408', 'alert-goods-quantity', '1.14', '库存预警', NULL);
|
@ -164,6 +164,9 @@ public class GoodsSku extends BaseEntity {
|
|||||||
@ApiModelProperty(value = "商品类型", required = true)
|
@ApiModelProperty(value = "商品类型", required = true)
|
||||||
private String goodsType;
|
private String goodsType;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "预警数量")
|
||||||
|
private Integer alertQuantity;
|
||||||
|
|
||||||
public Double getWeight() {
|
public Double getWeight() {
|
||||||
if (weight == null) {
|
if (weight == null) {
|
||||||
return 0d;
|
return 0d;
|
||||||
@ -171,6 +174,13 @@ public class GoodsSku extends BaseEntity {
|
|||||||
return weight;
|
return weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getalertQuantity() {
|
||||||
|
if(alertQuantity == null){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return alertQuantity;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date getCreateTime() {
|
public Date getCreateTime() {
|
||||||
if (super.getCreateTime() == null) {
|
if (super.getCreateTime() == null) {
|
||||||
@ -200,6 +210,7 @@ public class GoodsSku extends BaseEntity {
|
|||||||
this.mobileIntro = goods.getMobileIntro();
|
this.mobileIntro = goods.getMobileIntro();
|
||||||
this.goodsUnit = goods.getGoodsUnit();
|
this.goodsUnit = goods.getGoodsUnit();
|
||||||
this.grade = 100D;
|
this.grade = 100D;
|
||||||
|
this.alertQuantity = 0;
|
||||||
//商品状态
|
//商品状态
|
||||||
this.authFlag = goods.getAuthFlag();
|
this.authFlag = goods.getAuthFlag();
|
||||||
this.salesModel = goods.getSalesModel();
|
this.salesModel = goods.getSalesModel();
|
||||||
|
@ -90,6 +90,9 @@ public class GoodsSearchParams extends PageVO {
|
|||||||
@ApiModelProperty(value = "销售模式", required = true)
|
@ApiModelProperty(value = "销售模式", required = true)
|
||||||
private String salesModel;
|
private String salesModel;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "预警库存")
|
||||||
|
private Boolean alertQuantity;
|
||||||
|
|
||||||
public <T> QueryWrapper<T> queryWrapper() {
|
public <T> QueryWrapper<T> queryWrapper() {
|
||||||
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
|
||||||
if (CharSequenceUtil.isNotEmpty(goodsId)) {
|
if (CharSequenceUtil.isNotEmpty(goodsId)) {
|
||||||
@ -140,7 +143,9 @@ public class GoodsSearchParams extends PageVO {
|
|||||||
if (CharSequenceUtil.isNotEmpty(salesModel)) {
|
if (CharSequenceUtil.isNotEmpty(salesModel)) {
|
||||||
queryWrapper.eq("sales_model", salesModel);
|
queryWrapper.eq("sales_model", salesModel);
|
||||||
}
|
}
|
||||||
|
if(alertQuantity != null && alertQuantity){
|
||||||
|
queryWrapper.apply("quantity <= alert_quantity");
|
||||||
|
}
|
||||||
queryWrapper.in(CollUtil.isNotEmpty(ids), "id", ids);
|
queryWrapper.in(CollUtil.isNotEmpty(ids), "id", ids);
|
||||||
|
|
||||||
queryWrapper.eq("delete_flag", false);
|
queryWrapper.eq("delete_flag", false);
|
||||||
|
@ -21,5 +21,6 @@ public class GoodsSkuStockDTO {
|
|||||||
@ApiModelProperty(value = "库存")
|
@ApiModelProperty(value = "库存")
|
||||||
private Integer quantity;
|
private Integer quantity;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "预警库存")
|
||||||
|
private Integer alertQuantity;
|
||||||
}
|
}
|
||||||
|
@ -188,6 +188,18 @@ public interface GoodsSkuService extends IService<GoodsSku> {
|
|||||||
*/
|
*/
|
||||||
void updateStocks(List<GoodsSkuStockDTO> goodsSkuStockDTOS);
|
void updateStocks(List<GoodsSkuStockDTO> goodsSkuStockDTOS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新SKU预警库存
|
||||||
|
* @param goodsSkuStockDTOS sku库存修改实体
|
||||||
|
*/
|
||||||
|
void batchUpdateAlertQuantity(List<GoodsSkuStockDTO> goodsSkuStockDTOS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新SKU预警库存
|
||||||
|
* @param goodsSkuStockDTO sku库存修改实体
|
||||||
|
*/
|
||||||
|
void updateAlertQuantity(GoodsSkuStockDTO goodsSkuStockDTO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新SKU库存
|
* 更新SKU库存
|
||||||
*
|
*
|
||||||
|
@ -536,6 +536,36 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAlertQuantity(GoodsSkuStockDTO goodsSkuStockDTO) {
|
||||||
|
GoodsSku goodsSku = this.getById(goodsSkuStockDTO.getSkuId());
|
||||||
|
goodsSku.setAlertQuantity(goodsSkuStockDTO.getAlertQuantity());
|
||||||
|
//清除缓存,防止修改预警后直接修改商品导致预警数值错误
|
||||||
|
cache.remove(CachePrefix.GOODS.getPrefix() + goodsSku.getGoodsId());
|
||||||
|
this.update(goodsSku);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void batchUpdateAlertQuantity(List<GoodsSkuStockDTO> goodsSkuStockDTOS) {
|
||||||
|
List<GoodsSku> goodsSkuList = new ArrayList<>();
|
||||||
|
List<String> skuIds = goodsSkuStockDTOS.stream().map(GoodsSkuStockDTO::getSkuId).collect(Collectors.toList());
|
||||||
|
List<GoodsSkuStockDTO> goodsSkuStockList = this.baseMapper.queryStocks(GoodsSearchParams.builder().ids(skuIds).build().queryWrapper());
|
||||||
|
List<String> goodsIdList = goodsSkuStockList.stream().map(GoodsSkuStockDTO::getGoodsId).collect(Collectors.toList());
|
||||||
|
HashSet<String> uniqueSet = new HashSet<>(goodsIdList);
|
||||||
|
// 将去重后的元素转回列表
|
||||||
|
List<String> uniqueGoodsIdList = new ArrayList<>(uniqueSet);
|
||||||
|
for (String goodsId : uniqueGoodsIdList) {
|
||||||
|
cache.remove(CachePrefix.GOODS.getPrefix() + goodsId);
|
||||||
|
}
|
||||||
|
//修改预警库存
|
||||||
|
for (GoodsSkuStockDTO goodsSkuStockDTO : goodsSkuStockDTOS) {
|
||||||
|
GoodsSku goodsSku = this.getById(goodsSkuStockDTO.getSkuId());
|
||||||
|
goodsSku.setAlertQuantity(goodsSkuStockDTO.getAlertQuantity());
|
||||||
|
goodsSkuList.add(goodsSku);
|
||||||
|
}
|
||||||
|
this.updateBatchById(goodsSkuList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@ -64,7 +64,7 @@ public class GoodsSkuBuilder {
|
|||||||
Map<String, Object> specMap = new LinkedHashMap<>();
|
Map<String, Object> specMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
// 原始规格项
|
// 原始规格项
|
||||||
String[] ignoreOriginKeys = {"id", "sn", "cost", "price", "quantity", "weight"};
|
String[] ignoreOriginKeys = {"id", "sn", "cost", "price", "quantity", "weight", "alertQuantity"};
|
||||||
//获取规格信息
|
//获取规格信息
|
||||||
for (Map.Entry<String, Object> spec : skuInfo.entrySet()) {
|
for (Map.Entry<String, Object> spec : skuInfo.entrySet()) {
|
||||||
//保存新增规格信息
|
//保存新增规格信息
|
||||||
@ -91,6 +91,7 @@ public class GoodsSkuBuilder {
|
|||||||
goodsSku.setQuantity(Convert.toInt(skuInfo.get("quantity"), 0));
|
goodsSku.setQuantity(Convert.toInt(skuInfo.get("quantity"), 0));
|
||||||
goodsSku.setSpecs(JSONUtil.toJsonStr(specMap));
|
goodsSku.setSpecs(JSONUtil.toJsonStr(specMap));
|
||||||
goodsSku.setSimpleSpecs(simpleSpecs.toString());
|
goodsSku.setSimpleSpecs(simpleSpecs.toString());
|
||||||
|
goodsSku.setAlertQuantity(Convert.toInt(skuInfo.get("alertQuantity"), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,4 +27,7 @@ public interface GoodsStatisticsService extends IService<Goods> {
|
|||||||
* @return 今天的已上架的商品数量
|
* @return 今天的已上架的商品数量
|
||||||
*/
|
*/
|
||||||
long todayUpperNum();
|
long todayUpperNum();
|
||||||
|
|
||||||
|
long alertQuantityNum();
|
||||||
|
|
||||||
}
|
}
|
@ -59,4 +59,15 @@ public class GoodsStatisticsServiceImpl extends ServiceImpl<GoodsStatisticsMappe
|
|||||||
queryWrapper.ge(Goods::getCreateTime, DateUtil.beginOfDay(new DateTime()));
|
queryWrapper.ge(Goods::getCreateTime, DateUtil.beginOfDay(new DateTime()));
|
||||||
return this.count(queryWrapper);
|
return this.count(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long alertQuantityNum() {
|
||||||
|
QueryWrapper queryWrapper = new QueryWrapper();
|
||||||
|
AuthUser currentUser = Objects.requireNonNull(UserContext.getCurrentUser());
|
||||||
|
queryWrapper.eq(CharSequenceUtil.equals(currentUser.getRole().name(), UserEnums.STORE.name()),
|
||||||
|
"store_id", currentUser.getStoreId());
|
||||||
|
queryWrapper.eq("market_enable",GoodsStatusEnum.UPPER.name());
|
||||||
|
queryWrapper.apply("quantity < alert_quantity");
|
||||||
|
return goodsSkuService.count(queryWrapper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ public class IndexStatisticsServiceImpl implements IndexStatisticsService {
|
|||||||
Map<String, Object> map = storeFlowStatisticsService.getOrderStatisticsPrice();
|
Map<String, Object> map = storeFlowStatisticsService.getOrderStatisticsPrice();
|
||||||
storeIndexStatisticsVO.setOrderNum(Convert.toInt(map.get("num").toString()));
|
storeIndexStatisticsVO.setOrderNum(Convert.toInt(map.get("num").toString()));
|
||||||
storeIndexStatisticsVO.setOrderPrice(map.get("price") != null ? Double.parseDouble(map.get("price").toString()) : 0.0);
|
storeIndexStatisticsVO.setOrderPrice(map.get("price") != null ? Double.parseDouble(map.get("price").toString()) : 0.0);
|
||||||
|
storeIndexStatisticsVO.setAlertQuantityNum(goodsStatisticsService.alertQuantityNum());
|
||||||
//访问量
|
//访问量
|
||||||
StatisticsQueryParam queryParam = new StatisticsQueryParam();
|
StatisticsQueryParam queryParam = new StatisticsQueryParam();
|
||||||
queryParam.setSearchType(SearchTypeEnum.TODAY.name());
|
queryParam.setSearchType(SearchTypeEnum.TODAY.name());
|
||||||
|
@ -3,6 +3,7 @@ package cn.lili.controller.goods;
|
|||||||
import cn.lili.common.aop.annotation.DemoSite;
|
import cn.lili.common.aop.annotation.DemoSite;
|
||||||
import cn.lili.common.enums.ResultCode;
|
import cn.lili.common.enums.ResultCode;
|
||||||
import cn.lili.common.enums.ResultUtil;
|
import cn.lili.common.enums.ResultUtil;
|
||||||
|
import cn.lili.common.exception.RetryException;
|
||||||
import cn.lili.common.exception.ServiceException;
|
import cn.lili.common.exception.ServiceException;
|
||||||
import cn.lili.common.security.OperationalJudgment;
|
import cn.lili.common.security.OperationalJudgment;
|
||||||
import cn.lili.common.security.context.UserContext;
|
import cn.lili.common.security.context.UserContext;
|
||||||
@ -18,22 +19,26 @@ import cn.lili.modules.goods.entity.vos.GoodsVO;
|
|||||||
import cn.lili.modules.goods.entity.vos.StockWarningVO;
|
import cn.lili.modules.goods.entity.vos.StockWarningVO;
|
||||||
import cn.lili.modules.goods.service.GoodsService;
|
import cn.lili.modules.goods.service.GoodsService;
|
||||||
import cn.lili.modules.goods.service.GoodsSkuService;
|
import cn.lili.modules.goods.service.GoodsSkuService;
|
||||||
|
import cn.lili.modules.search.service.EsGoodsIndexService;
|
||||||
import cn.lili.modules.statistics.aop.PageViewPoint;
|
import cn.lili.modules.statistics.aop.PageViewPoint;
|
||||||
import cn.lili.modules.statistics.aop.enums.PageViewEnum;
|
import cn.lili.modules.statistics.aop.enums.PageViewEnum;
|
||||||
import cn.lili.modules.store.entity.dos.StoreDetail;
|
import cn.lili.modules.store.entity.dos.StoreDetail;
|
||||||
import cn.lili.modules.store.service.StoreDetailService;
|
import cn.lili.modules.store.service.StoreDetailService;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import io.swagger.annotations.Api;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
import io.swagger.annotations.*;
|
||||||
import io.swagger.annotations.ApiImplicitParams;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.elasticsearch.action.ActionListener;
|
||||||
|
import org.elasticsearch.client.RequestOptions;
|
||||||
|
import org.elasticsearch.index.reindex.BulkByScrollResponse;
|
||||||
|
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -67,6 +72,9 @@ public class GoodsStoreController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private StoreDetailService storeDetailService;
|
private StoreDetailService storeDetailService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EsGoodsIndexService esGoodsIndexService;
|
||||||
|
|
||||||
@ApiOperation(value = "分页获取商品列表")
|
@ApiOperation(value = "分页获取商品列表")
|
||||||
@GetMapping(value = "/list")
|
@GetMapping(value = "/list")
|
||||||
public ResultMessage<IPage<Goods>> getByPage(GoodsSearchParams goodsSearchParams) {
|
public ResultMessage<IPage<Goods>> getByPage(GoodsSearchParams goodsSearchParams) {
|
||||||
@ -87,17 +95,36 @@ public class GoodsStoreController {
|
|||||||
|
|
||||||
@ApiOperation(value = "分页获取库存告警商品列表")
|
@ApiOperation(value = "分页获取库存告警商品列表")
|
||||||
@GetMapping(value = "/list/stock")
|
@GetMapping(value = "/list/stock")
|
||||||
public ResultMessage<StockWarningVO> getWarningStockByPage(GoodsSearchParams goodsSearchParams) {
|
public ResultMessage<IPage<GoodsSku>> getWarningStockByPage(GoodsSearchParams goodsSearchParams) {
|
||||||
//获取当前登录商家账号
|
//获取当前登录商家账号
|
||||||
String storeId = Objects.requireNonNull(UserContext.getCurrentUser()).getStoreId();
|
String storeId = Objects.requireNonNull(UserContext.getCurrentUser()).getStoreId();
|
||||||
StoreDetail storeDetail = OperationalJudgment.judgment(storeDetailService.getStoreDetail(storeId));
|
|
||||||
Integer stockWarnNum = storeDetail.getStockWarning();
|
|
||||||
goodsSearchParams.setStoreId(storeId);
|
goodsSearchParams.setStoreId(storeId);
|
||||||
goodsSearchParams.setLeQuantity(stockWarnNum);
|
goodsSearchParams.setAlertQuantity(true);
|
||||||
goodsSearchParams.setMarketEnable(GoodsStatusEnum.UPPER.name());
|
goodsSearchParams.setMarketEnable(GoodsStatusEnum.UPPER.name());
|
||||||
IPage<GoodsSku> goodsSku = goodsSkuService.getGoodsSkuByPage(goodsSearchParams);
|
IPage<GoodsSku> goodsSkuPage = goodsSkuService.getGoodsSkuByPage(goodsSearchParams);
|
||||||
StockWarningVO stockWarning = new StockWarningVO(stockWarnNum, goodsSku);
|
return ResultUtil.data(goodsSkuPage);
|
||||||
return ResultUtil.data(stockWarning);
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "批量修改商品预警库存")
|
||||||
|
@PutMapping(value = "/batch/update/alert/stocks", consumes = "application/json")
|
||||||
|
public ResultMessage<Object> batchUpdateAlertQuantity(@RequestBody List<GoodsSkuStockDTO> updateStockList) {
|
||||||
|
String storeId = Objects.requireNonNull(UserContext.getCurrentUser()).getStoreId();
|
||||||
|
// 获取商品skuId集合
|
||||||
|
List<String> goodsSkuIds = updateStockList.stream().map(GoodsSkuStockDTO::getSkuId).collect(Collectors.toList());
|
||||||
|
// 根据skuId集合查询商品信息
|
||||||
|
List<GoodsSku> goodsSkuList = goodsSkuService.list(new LambdaQueryWrapper<GoodsSku>().in(GoodsSku::getId, goodsSkuIds).eq(GoodsSku::getStoreId, storeId));
|
||||||
|
// 过滤不符合当前店铺的商品
|
||||||
|
List<String> filterGoodsSkuIds = goodsSkuList.stream().map(GoodsSku::getId).collect(Collectors.toList());
|
||||||
|
List<GoodsSkuStockDTO> collect = updateStockList.stream().filter(i -> filterGoodsSkuIds.contains(i.getSkuId())).collect(Collectors.toList());
|
||||||
|
goodsSkuService.batchUpdateAlertQuantity(collect);
|
||||||
|
return ResultUtil.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "修改商品预警库存")
|
||||||
|
@PutMapping(value = "/update/alert/stocks", consumes = "application/json")
|
||||||
|
public ResultMessage<Object> updateAlertQuantity(@RequestBody GoodsSkuStockDTO goodsSkuStockDTO) {
|
||||||
|
goodsSkuService.updateAlertQuantity(goodsSkuStockDTO);
|
||||||
|
return ResultUtil.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user