耗材联动更新
This commit is contained in:
@@ -11,6 +11,7 @@ import com.czg.log.annotation.OperationLog;
|
|||||||
import com.czg.product.dto.ProdConsBindDTO;
|
import com.czg.product.dto.ProdConsBindDTO;
|
||||||
import com.czg.product.dto.ProdSkuDTO;
|
import com.czg.product.dto.ProdSkuDTO;
|
||||||
import com.czg.product.dto.ProductDTO;
|
import com.czg.product.dto.ProductDTO;
|
||||||
|
import com.czg.product.entity.ProductStockFlow;
|
||||||
import com.czg.product.param.*;
|
import com.czg.product.param.*;
|
||||||
import com.czg.product.service.ProdConsRelationService;
|
import com.czg.product.service.ProdConsRelationService;
|
||||||
import com.czg.product.service.ProductService;
|
import com.czg.product.service.ProductService;
|
||||||
@@ -117,6 +118,17 @@ public class ProductController {
|
|||||||
return CzgResult.success();
|
return CzgResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品-库存变动记录
|
||||||
|
*/
|
||||||
|
@GetMapping("stockFlow")
|
||||||
|
@OperationLog("商品-库存变动记录")
|
||||||
|
//@SaAdminCheckPermission("consStockFlow:flow")
|
||||||
|
public CzgResult<Page<ProductStockFlow>> stockFlow(ProductStockFlowParam param) {
|
||||||
|
Page<ProductStockFlow> data = productService.findProductStockFlowPage(param);
|
||||||
|
return CzgResult.success(data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品-修改
|
* 商品-修改
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -39,10 +39,12 @@ public class ConsStockFlow implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private Long vendorId;
|
private Long vendorId;
|
||||||
/**
|
/**
|
||||||
|
* {@link com.czg.product.enums.InOutTypeEnum}
|
||||||
* 出入库类型 in-入库 out-出库
|
* 出入库类型 in-入库 out-出库
|
||||||
*/
|
*/
|
||||||
private String inOutType;
|
private String inOutType;
|
||||||
/**
|
/**
|
||||||
|
* {@link com.czg.product.enums.InOutItemEnum}
|
||||||
* 出入库名目 manual-in:手动入库 manual-out:手动出库 win-in:盘盈入库 loss-out:盘亏出库 order-in:订单退款入库 order-out:订单消费出库 damage-out:损耗出库
|
* 出入库名目 manual-in:手动入库 manual-out:手动出库 win-in:盘盈入库 loss-out:盘亏出库 order-in:订单退款入库 order-out:订单消费出库 damage-out:损耗出库
|
||||||
*/
|
*/
|
||||||
private String inOutItem;
|
private String inOutItem;
|
||||||
|
|||||||
@@ -30,4 +30,6 @@ public interface ProdConsRelationService extends IService<ProdConsRelation> {
|
|||||||
*/
|
*/
|
||||||
void saveProdConsRelation(ProdConsBindDTO dto);
|
void saveProdConsRelation(ProdConsBindDTO dto);
|
||||||
|
|
||||||
|
List<ProdConsRelationDTO> selectListByProdId(Long prodId);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,19 @@
|
|||||||
package com.czg.product.service;
|
package com.czg.product.service;
|
||||||
|
|
||||||
import com.czg.product.dto.ProductDTO;
|
import com.czg.product.dto.ProductDTO;
|
||||||
|
import com.czg.product.entity.ConsStockFlow;
|
||||||
import com.czg.product.entity.Product;
|
import com.czg.product.entity.Product;
|
||||||
|
import com.czg.product.entity.ProductStockFlow;
|
||||||
|
import com.czg.product.enums.InOutItemEnum;
|
||||||
|
import com.czg.product.enums.InOutTypeEnum;
|
||||||
import com.czg.product.param.*;
|
import com.czg.product.param.*;
|
||||||
import com.czg.product.vo.ProductStatisticsVo;
|
import com.czg.product.vo.ProductStatisticsVo;
|
||||||
|
import com.czg.product.vo.ProductStockVO;
|
||||||
import com.mybatisflex.core.paginate.Page;
|
import com.mybatisflex.core.paginate.Page;
|
||||||
import com.mybatisflex.core.service.IService;
|
import com.mybatisflex.core.service.IService;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -39,7 +45,7 @@ public interface ProductService extends IService<Product> {
|
|||||||
/**
|
/**
|
||||||
* 从缓存里面获取商品列表
|
* 从缓存里面获取商品列表
|
||||||
*
|
*
|
||||||
* @param shopId 店铺ID
|
* @param shopId 店铺ID
|
||||||
* @param categoryId 商品分类ID
|
* @param categoryId 商品分类ID
|
||||||
* @return 商品列表数据
|
* @return 商品列表数据
|
||||||
*/
|
*/
|
||||||
@@ -115,4 +121,17 @@ public interface ProductService extends IService<Product> {
|
|||||||
* @param param 商品统计入参
|
* @param param 商品统计入参
|
||||||
*/
|
*/
|
||||||
ProductStatisticsVo getProductStatistics(ProductInfoParam param);
|
ProductStatisticsVo getProductStatistics(ProductInfoParam param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品出入库流水查询
|
||||||
|
*
|
||||||
|
* @param param 查询参数
|
||||||
|
* @return 分页数据
|
||||||
|
*/
|
||||||
|
Page<ProductStockFlow> findProductStockFlowPage(ProductStockFlowParam param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过商品 进行耗材库存增减
|
||||||
|
*/
|
||||||
|
void consStockByProduct(InOutTypeEnum type, InOutItemEnum item, List<ProductStockVO> products, Long orderId, String remark);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.czg.product.vo;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 产品库存VO
|
||||||
|
* @author ww
|
||||||
|
*/
|
||||||
|
public record ProductStockVO(Long productId, BigDecimal number) {
|
||||||
|
}
|
||||||
@@ -75,4 +75,9 @@ public class ProdConsRelationServiceImpl extends ServiceImpl<ProdConsRelationMap
|
|||||||
mapper.insertBatchSelective(entityList, 50);
|
mapper.insertBatchSelective(entityList, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ProdConsRelationDTO> selectListByProdId(Long prodId) {
|
||||||
|
return mapper.selectListByProdId(prodId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,9 @@ import com.czg.product.enums.InOutItemEnum;
|
|||||||
import com.czg.product.enums.InOutTypeEnum;
|
import com.czg.product.enums.InOutTypeEnum;
|
||||||
import com.czg.product.service.ConsStockFlowService;
|
import com.czg.product.service.ConsStockFlowService;
|
||||||
import com.czg.product.service.ProductRpcService;
|
import com.czg.product.service.ProductRpcService;
|
||||||
|
import com.czg.product.service.ProductService;
|
||||||
import com.czg.product.service.ProductStockFlowService;
|
import com.czg.product.service.ProductStockFlowService;
|
||||||
|
import com.czg.product.vo.ProductStockVO;
|
||||||
import com.czg.product.vo.ProductVO;
|
import com.czg.product.vo.ProductVO;
|
||||||
import com.czg.service.RedisService;
|
import com.czg.service.RedisService;
|
||||||
import com.czg.service.product.mapper.ConsInfoMapper;
|
import com.czg.service.product.mapper.ConsInfoMapper;
|
||||||
@@ -31,6 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -49,142 +52,38 @@ public class ProductRpcServiceImpl implements ProductRpcService {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ProductMapper productMapper;
|
private ProductMapper productMapper;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ProdConsRelationMapper prodConsRelationMapper;
|
private ProductService productService;
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ConsInfoMapper consInfoMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ConsStockFlowService consStockFlowService;
|
|
||||||
@Resource
|
|
||||||
private ProductStockFlowService productStockFlowService;
|
|
||||||
@Resource
|
|
||||||
private RabbitPublisher rabbitPublisher;
|
|
||||||
@Resource
|
@Resource
|
||||||
private RedisService redisService;
|
private RedisService redisService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
//@CacheEvict(value = {CacheConstant.USER_CLIENT_HOTS_PRODUCT, CacheConstant.USER_CLIENT_GROUPS_PRODUCT, ADMIN_CLIENT_PRODUCT_LIST}, key = "#shopId", allEntries = true, beforeInvocation = true)
|
|
||||||
public void paySuccessSubtractStock(Long shopId, Long orderId, List<Map<String, Object>> dataList) {
|
public void paySuccessSubtractStock(Long shopId, Long orderId, List<Map<String, Object>> dataList) {
|
||||||
List<ProductStockSubtractDTO> list = BeanUtil.copyToList(dataList, ProductStockSubtractDTO.class);
|
List<ProductStockSubtractDTO> list = BeanUtil.copyToList(dataList, ProductStockSubtractDTO.class);
|
||||||
if (CollUtil.isEmpty(list)) {
|
if (CollUtil.isEmpty(list)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//TODO 优化耗材库存更新逻辑 耗材预警
|
List<ProductStockVO> productStockList = new ArrayList<>();
|
||||||
boolean isLowWarnLine = false;
|
|
||||||
for (ProductStockSubtractDTO dto : list) {
|
for (ProductStockSubtractDTO dto : list) {
|
||||||
Product product = productMapper.selectOneById(dto.getProductId());
|
productStockList.add(new ProductStockVO(dto.getProductId(), dto.getNum()));
|
||||||
if (product == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// 查询商品绑定耗材信息
|
|
||||||
List<ProdConsRelation> relationList = prodConsRelationMapper.selectListByQuery(QueryWrapper.create().eq(ProdConsRelation::getProductId, dto.getProductId()));
|
|
||||||
if (CollUtil.isEmpty(relationList)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (ProdConsRelation prodConsRelation : relationList) {
|
|
||||||
// 耗材id
|
|
||||||
Long consInfoId = prodConsRelation.getConsInfoId();
|
|
||||||
// 耗材消耗数量
|
|
||||||
BigDecimal surplusStock = prodConsRelation.getSurplusStock();
|
|
||||||
if (surplusStock == null || surplusStock.compareTo(BigDecimal.ZERO) == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// 实际消耗数量 = 耗材消耗数量 * 商品购买数量
|
|
||||||
surplusStock = NumberUtil.mul(surplusStock, dto.getNum());
|
|
||||||
ConsInfo consInfo = consInfoMapper.selectOneById(consInfoId);
|
|
||||||
if (consInfo == null || consInfo.getIsStock() == SystemConstants.OneZero.ZERO) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
BigDecimal stockNumber = consInfo.getStockNumber();
|
|
||||||
consInfo.setStockNumber(NumberUtil.sub(stockNumber, surplusStock));
|
|
||||||
// 更新耗材库存数量
|
|
||||||
consInfoMapper.update(consInfo);
|
|
||||||
// 插入耗材流水记录
|
|
||||||
ConsStockFlow consStockFlow = new ConsStockFlow();
|
|
||||||
consStockFlow.setShopId(shopId);
|
|
||||||
consStockFlow.setVendorId(null);
|
|
||||||
consStockFlow.setInOutType(InOutTypeEnum.OUT.value());
|
|
||||||
consStockFlow.setInOutItem(InOutItemEnum.ORDER_OUT.value());
|
|
||||||
consStockFlow.setInOutDate(LocalDate.now());
|
|
||||||
consStockFlow.setConId(consInfo.getId());
|
|
||||||
consStockFlow.setConName(consInfo.getConName());
|
|
||||||
consStockFlow.setUnitName(consInfo.getConUnit());
|
|
||||||
consStockFlow.setBeforeNumber(stockNumber);
|
|
||||||
consStockFlow.setInOutNumber(NumberUtil.sub(BigDecimal.ZERO, surplusStock));
|
|
||||||
consStockFlow.setAfterNumber(consInfo.getStockNumber());
|
|
||||||
consStockFlow.setSubTotal(NumberUtil.mul(surplusStock, consInfo.getPrice()));
|
|
||||||
consStockFlow.setProductId(dto.getProductId());
|
|
||||||
//consStockFlow.setSkuId(0L);
|
|
||||||
consStockFlow.setOrderId(orderId);
|
|
||||||
consStockFlowService.saveFlow(consStockFlow);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (isLowWarnLine) {
|
productService.consStockByProduct(InOutTypeEnum.OUT, InOutItemEnum.ORDER_OUT, productStockList, orderId, "订单消费");
|
||||||
ThreadUtil.execAsync(() -> rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)));
|
|
||||||
}
|
|
||||||
log.info("ProductService.--------------------------------------------库存更新成功");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
//@CacheEvict(value = {CacheConstant.USER_CLIENT_HOTS_PRODUCT, CacheConstant.USER_CLIENT_GROUPS_PRODUCT, ADMIN_CLIENT_PRODUCT_LIST}, key = "#shopId", allEntries = true, beforeInvocation = true)
|
|
||||||
public void orderCancelRecoverStock(Long shopId, Long orderId, List<Map<String, Object>> dataList) {
|
public void orderCancelRecoverStock(Long shopId, Long orderId, List<Map<String, Object>> dataList) {
|
||||||
List<ProductStockSubtractDTO> list = BeanUtil.copyToList(dataList, ProductStockSubtractDTO.class);
|
List<ProductStockSubtractDTO> list = BeanUtil.copyToList(dataList, ProductStockSubtractDTO.class);
|
||||||
if (CollUtil.isEmpty(list)) {
|
if (CollUtil.isEmpty(list)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean isLowWarnLine = false;
|
List<ProductStockVO> productStockList = new ArrayList<>();
|
||||||
for (ProductStockSubtractDTO dto : list) {
|
for (ProductStockSubtractDTO dto : list) {
|
||||||
// 查询商品绑定耗材信息
|
productStockList.add(new ProductStockVO(dto.getProductId(), dto.getNum()));
|
||||||
List<ProdConsRelation> relationList = prodConsRelationMapper.selectListByQuery(QueryWrapper.create().eq(ProdConsRelation::getProductId, dto.getProductId()));
|
|
||||||
if (CollUtil.isEmpty(relationList)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (ProdConsRelation prodConsRelation : relationList) {
|
|
||||||
// 耗材id
|
|
||||||
Long consInfoId = prodConsRelation.getConsInfoId();
|
|
||||||
// 耗材消耗数量
|
|
||||||
BigDecimal surplusStock = prodConsRelation.getSurplusStock();
|
|
||||||
if (surplusStock == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// 实际消耗数量 = 耗材消耗数量 * 商品购买数量
|
|
||||||
surplusStock = NumberUtil.mul(surplusStock, dto.getNum());
|
|
||||||
ConsInfo consInfo = consInfoMapper.selectOneById(consInfoId);
|
|
||||||
if (consInfo == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
BigDecimal stockNumber = consInfo.getStockNumber();
|
|
||||||
consInfo.setStockNumber(NumberUtil.add(stockNumber, surplusStock));
|
|
||||||
// 更新耗材库存数量
|
|
||||||
consInfoMapper.update(consInfo);
|
|
||||||
// 插入耗材流水记录
|
|
||||||
ConsStockFlow consStockFlow = new ConsStockFlow();
|
|
||||||
consStockFlow.setShopId(shopId);
|
|
||||||
consStockFlow.setInOutType(InOutTypeEnum.OUT.value());
|
|
||||||
consStockFlow.setInOutItem(InOutItemEnum.ORDER_OUT.value());
|
|
||||||
consStockFlow.setInOutDate(LocalDate.now());
|
|
||||||
consStockFlow.setConId(consInfo.getId());
|
|
||||||
consStockFlow.setConName(consInfo.getConName());
|
|
||||||
consStockFlow.setUnitName(consInfo.getConUnit());
|
|
||||||
consStockFlow.setBeforeNumber(stockNumber);
|
|
||||||
consStockFlow.setInOutNumber(surplusStock);
|
|
||||||
consStockFlow.setAfterNumber(consInfo.getStockNumber());
|
|
||||||
consStockFlow.setSubTotal(NumberUtil.mul(surplusStock, consInfo.getPrice()));
|
|
||||||
consStockFlow.setProductId(dto.getProductId());
|
|
||||||
consStockFlow.setRemark("红冲订单取消/退菜/退单消耗的库存");
|
|
||||||
consStockFlow.setOrderId(orderId);
|
|
||||||
consStockFlowService.saveFlow(consStockFlow);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (isLowWarnLine) {
|
productService.consStockByProduct(InOutTypeEnum.IN, InOutItemEnum.ORDER_IN, productStockList, orderId, "订单取消/过期返还库存");
|
||||||
ThreadUtil.execAsync(() -> rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)));
|
|
||||||
}
|
|
||||||
log.info("ProductService.--------------------------------------------库存更新成功");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -194,54 +93,11 @@ public class ProductRpcServiceImpl implements ProductRpcService {
|
|||||||
if (CollUtil.isEmpty(list)) {
|
if (CollUtil.isEmpty(list)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean isLowWarnLine = false;
|
List<ProductStockVO> productStockList = new ArrayList<>();
|
||||||
for (ProductStockSubtractDTO dto : list) {
|
for (ProductStockSubtractDTO dto : list) {
|
||||||
// 查询商品绑定耗材信息
|
productStockList.add(new ProductStockVO(dto.getProductId(), dto.getNum()));
|
||||||
List<ProdConsRelation> relationList = prodConsRelationMapper.selectListByQuery(QueryWrapper.create().eq(ProdConsRelation::getProductId, dto.getProductId()));
|
|
||||||
if (CollUtil.isEmpty(relationList)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (ProdConsRelation prodConsRelation : relationList) {
|
|
||||||
// 耗材id
|
|
||||||
Long consInfoId = prodConsRelation.getConsInfoId();
|
|
||||||
// 耗材消耗数量
|
|
||||||
BigDecimal surplusStock = prodConsRelation.getSurplusStock();
|
|
||||||
if (surplusStock == null || surplusStock.compareTo(BigDecimal.ZERO) == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// 实际消耗数量 = 耗材消耗数量 * 商品购买数量
|
|
||||||
surplusStock = NumberUtil.mul(surplusStock, dto.getNum());
|
|
||||||
ConsInfo consInfo = consInfoMapper.selectOneById(consInfoId);
|
|
||||||
if (consInfo == null || consInfo.getIsStock() == SystemConstants.OneZero.ZERO || consInfo.getIsRefundStock() == SystemConstants.OneZero.ZERO) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
BigDecimal stockNumber = consInfo.getStockNumber();
|
|
||||||
consInfo.setStockNumber(NumberUtil.add(stockNumber, surplusStock));
|
|
||||||
// 更新耗材库存数量
|
|
||||||
consInfoMapper.update(consInfo);
|
|
||||||
// 插入耗材流水记录
|
|
||||||
ConsStockFlow consStockFlow = new ConsStockFlow();
|
|
||||||
consStockFlow.setShopId(shopId);
|
|
||||||
consStockFlow.setInOutType(InOutTypeEnum.OUT.value());
|
|
||||||
consStockFlow.setInOutItem(InOutItemEnum.ORDER_OUT.value());
|
|
||||||
consStockFlow.setInOutDate(LocalDate.now());
|
|
||||||
consStockFlow.setConId(consInfo.getId());
|
|
||||||
consStockFlow.setConName(consInfo.getConName());
|
|
||||||
consStockFlow.setUnitName(consInfo.getConUnit());
|
|
||||||
consStockFlow.setBeforeNumber(stockNumber);
|
|
||||||
consStockFlow.setInOutNumber(surplusStock);
|
|
||||||
consStockFlow.setAfterNumber(consInfo.getStockNumber());
|
|
||||||
consStockFlow.setSubTotal(NumberUtil.mul(surplusStock, consInfo.getPrice()));
|
|
||||||
consStockFlow.setProductId(dto.getProductId());
|
|
||||||
consStockFlow.setOrderId(orderId);
|
|
||||||
consStockFlow.setRemark("红冲订单取消/退菜/退单消耗的库存");
|
|
||||||
consStockFlowService.saveFlow(consStockFlow);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (isLowWarnLine) {
|
productService.consStockByProduct(InOutTypeEnum.IN, InOutItemEnum.ORDER_IN, productStockList, orderId, "订单退菜/退款返还库存");
|
||||||
ThreadUtil.execAsync(() -> rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)));
|
|
||||||
}
|
|
||||||
log.info("ProductService.--------------------------------------------库存更新成功");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -254,13 +110,4 @@ public class ProductRpcServiceImpl implements ProductRpcService {
|
|||||||
String key = ADMIN_CLIENT_PRODUCT_LIST + "::" + shopId + "::" + categoryId;
|
String key = ADMIN_CLIENT_PRODUCT_LIST + "::" + shopId + "::" + categoryId;
|
||||||
redisService.del(key);
|
redisService.del(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshRedisProdStock(Long shopId, Long productId, BigDecimal stockNumber) {
|
|
||||||
String key = StrUtil.format(SHOP_PRODUCT_STOCK, shopId, productId);
|
|
||||||
if (NumberUtil.isLessOrEqual(stockNumber, BigDecimal.ZERO)) {
|
|
||||||
redisService.del(key);
|
|
||||||
} else {
|
|
||||||
redisService.set(key, stockNumber.intValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -21,21 +21,22 @@ import com.czg.product.param.*;
|
|||||||
import com.czg.product.service.*;
|
import com.czg.product.service.*;
|
||||||
import com.czg.product.vo.ProductGroupVo;
|
import com.czg.product.vo.ProductGroupVo;
|
||||||
import com.czg.product.vo.ProductStatisticsVo;
|
import com.czg.product.vo.ProductStatisticsVo;
|
||||||
|
import com.czg.product.vo.ProductStockVO;
|
||||||
import com.czg.sa.StpKit;
|
import com.czg.sa.StpKit;
|
||||||
import com.czg.service.RedisService;
|
import com.czg.service.RedisService;
|
||||||
import com.czg.service.product.mapper.*;
|
import com.czg.service.product.mapper.*;
|
||||||
import com.czg.utils.PageUtil;
|
import com.czg.utils.PageUtil;
|
||||||
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import com.github.pagehelper.PageInfo;
|
||||||
import com.mybatisflex.core.paginate.Page;
|
import com.mybatisflex.core.paginate.Page;
|
||||||
import com.mybatisflex.core.query.QueryWrapper;
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
import com.mybatisflex.core.update.UpdateChain;
|
import com.mybatisflex.core.update.UpdateChain;
|
||||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.dubbo.config.annotation.DubboService;
|
import org.apache.dubbo.config.annotation.DubboService;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.context.annotation.Lazy;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@@ -63,17 +64,14 @@ import static com.czg.product.entity.table.ShopProdUnitTableDef.SHOP_PROD_UNIT;
|
|||||||
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
|
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
|
||||||
|
|
||||||
private final ProdSkuMapper prodSkuMapper;
|
private final ProdSkuMapper prodSkuMapper;
|
||||||
private final ProdConsRelationMapper prodConsRelationMapper;
|
private final ProdConsRelationService prodConsRelationService;
|
||||||
private final ConsInfoMapper consInfoMapper;
|
private final ConsInfoMapper consInfoMapper;
|
||||||
private final ProductStockFlowMapper productStockFlowMapper;
|
private final ProductStockFlowMapper productStockFlowMapper;
|
||||||
private final ProductStockFlowService productStockFlowService;
|
|
||||||
private final ConsStockFlowService consStockFlowService;
|
private final ConsStockFlowService consStockFlowService;
|
||||||
private final SensitiveOperationService sensitiveOperationService;
|
private final SensitiveOperationService sensitiveOperationService;
|
||||||
private final ProdGroupRelationMapper prodGroupRelationMapper;
|
private final ProdGroupRelationMapper prodGroupRelationMapper;
|
||||||
|
private final ProductStockFlowService productStockFlowService;
|
||||||
private final RedisService redisService;
|
private final RedisService redisService;
|
||||||
@Resource
|
|
||||||
@Lazy
|
|
||||||
private ShopProdCategoryService shopProdCategoryService;
|
|
||||||
|
|
||||||
private QueryWrapper buildQueryWrapper(ProductDTO param) {
|
private QueryWrapper buildQueryWrapper(ProductDTO param) {
|
||||||
QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
|
QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
|
||||||
@@ -147,7 +145,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||||||
lowMemberPriceIsPresent.ifPresent(record::setLowMemberPrice);
|
lowMemberPriceIsPresent.ifPresent(record::setLowMemberPrice);
|
||||||
}
|
}
|
||||||
record.setSkuList(skuList);
|
record.setSkuList(skuList);
|
||||||
List<ProdConsRelationDTO> consList = prodConsRelationMapper.selectListByProdId(record.getId());
|
List<ProdConsRelationDTO> consList = prodConsRelationService.selectListByProdId(record.getId());
|
||||||
record.setConsList(consList);
|
record.setConsList(consList);
|
||||||
if (CollUtil.isNotEmpty(consList)) {
|
if (CollUtil.isNotEmpty(consList)) {
|
||||||
List<Long> consIds = consList.stream().map(ProdConsRelationDTO::getConsInfoId).distinct().toList();
|
List<Long> consIds = consList.stream().map(ProdConsRelationDTO::getConsInfoId).distinct().toList();
|
||||||
@@ -181,7 +179,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||||||
lowMemberPriceIsPresent.ifPresent(record::setLowMemberPrice);
|
lowMemberPriceIsPresent.ifPresent(record::setLowMemberPrice);
|
||||||
}
|
}
|
||||||
record.setSkuList(skuList);
|
record.setSkuList(skuList);
|
||||||
record.setProdConsRelations(prodConsRelationMapper.selectListByQuery(query()
|
record.setProdConsRelations(prodConsRelationService.list(query()
|
||||||
.eq(ProdConsRelation::getProductId, record.getId())
|
.eq(ProdConsRelation::getProductId, record.getId())
|
||||||
.eq(ProdConsRelation::getShopId, record.getShopId())));
|
.eq(ProdConsRelation::getShopId, record.getShopId())));
|
||||||
});
|
});
|
||||||
@@ -438,7 +436,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||||||
}
|
}
|
||||||
List<ProdSkuDTO> skuList = prodSkuMapper.selectListByQueryAs(query().eq(ProdSku::getProductId, id).eq(ProdSku::getIsDel, SystemConstants.OneZero.ZERO), ProdSkuDTO.class);
|
List<ProdSkuDTO> skuList = prodSkuMapper.selectListByQueryAs(query().eq(ProdSku::getProductId, id).eq(ProdSku::getIsDel, SystemConstants.OneZero.ZERO), ProdSkuDTO.class);
|
||||||
dto.setSkuList(skuList);
|
dto.setSkuList(skuList);
|
||||||
List<ProdConsRelationDTO> consList = prodConsRelationMapper.selectListByProdId(dto.getId());
|
List<ProdConsRelationDTO> consList = prodConsRelationService.selectListByProdId(dto.getId());
|
||||||
dto.setConsList(consList);
|
dto.setConsList(consList);
|
||||||
dto.setRelatedRecommendJson(getRelateProductList(dto.getRelatedRecommend()));
|
dto.setRelatedRecommendJson(getRelateProductList(dto.getRelatedRecommend()));
|
||||||
return dto;
|
return dto;
|
||||||
@@ -487,6 +485,10 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||||||
}
|
}
|
||||||
prodSkuMapper.insertBatch(prodSkuList);
|
prodSkuMapper.insertBatch(prodSkuList);
|
||||||
}
|
}
|
||||||
|
ProdConsBindDTO prodConsBindDTO = new ProdConsBindDTO();
|
||||||
|
prodConsBindDTO.setId(null);
|
||||||
|
prodConsBindDTO.setConsList(dto.getConsList());
|
||||||
|
prodConsRelationService.saveProdConsRelation(prodConsBindDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -571,7 +573,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||||||
.eq(Product::getShopId, shopId)
|
.eq(Product::getShopId, shopId)
|
||||||
.update();
|
.update();
|
||||||
prodGroupRelationMapper.deleteByQuery(query().eq(ProdGroupRelation::getProductId, id));
|
prodGroupRelationMapper.deleteByQuery(query().eq(ProdGroupRelation::getProductId, id));
|
||||||
prodConsRelationMapper.deleteByQuery(query().eq(ProdConsRelation::getProductId, id));
|
prodConsRelationService.remove(query().eq(ProdConsRelation::getProductId, id));
|
||||||
// 清除商品分类列表缓存
|
// 清除商品分类列表缓存
|
||||||
clearProductCache(categoryId);
|
clearProductCache(categoryId);
|
||||||
}
|
}
|
||||||
@@ -709,39 +711,27 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||||||
Long shopId = StpKit.USER.getShopId();
|
Long shopId = StpKit.USER.getShopId();
|
||||||
Long createUserId = StpKit.USER.getLoginIdAsLong();
|
Long createUserId = StpKit.USER.getLoginIdAsLong();
|
||||||
String createUserName = StpKit.USER.getAccount();
|
String createUserName = StpKit.USER.getAccount();
|
||||||
// 如果绑定了耗材,则同步更新耗材库存
|
Product product = mapper.selectOneById(param.getProductId());
|
||||||
List<ProdConsRelationDTO> consList = prodConsRelationMapper.selectListByProdId(param.getProductId());
|
if (product == null) {
|
||||||
if (CollUtil.isEmpty(consList)) {
|
throw new CzgException("商品不存在");
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (ProdConsRelationDTO consInfo : consList) {
|
|
||||||
ConsStockFlow entity = new ConsStockFlow();
|
|
||||||
entity.setCreateUserId(createUserId);
|
|
||||||
entity.setCreateUserName(createUserName);
|
|
||||||
entity.setShopId(shopId);
|
|
||||||
entity.setConId(consInfo.getConsInfoId());
|
|
||||||
entity.setConName(consInfo.getConName());
|
|
||||||
entity.setPurchasePrice(consInfo.getPrice());
|
|
||||||
BigDecimal inOutNumber = NumberUtil.mul(param.getNumber(), consInfo.getSurplusStock());
|
|
||||||
BigDecimal balance = NumberUtil.sub(consInfo.getStockNumber(), inOutNumber);
|
|
||||||
if (NumberUtil.isLess(balance, BigDecimal.ZERO)) {
|
|
||||||
throw new CzgException(StrUtil.format("耗材{}存在发生变动,请刷新后重试", entity.getConName()));
|
|
||||||
}
|
|
||||||
entity.setBeforeNumber(consInfo.getStockNumber());
|
|
||||||
entity.setInOutNumber(NumberUtil.sub(BigDecimal.ZERO, inOutNumber));
|
|
||||||
entity.setAfterNumber(balance);
|
|
||||||
entity.setInOutType(InOutTypeEnum.OUT.value());
|
|
||||||
entity.setInOutItem(InOutItemEnum.DAMAGE_OUT.value());
|
|
||||||
entity.setSubTotal(NumberUtil.mul(inOutNumber, consInfo.getPrice()));
|
|
||||||
entity.setImgUrls(JSON.toJSONString(param.getImgUrls()));
|
|
||||||
entity.setRemark("【商品报损,自动报损相关耗材】" + StrUtil.nullToDefault(param.getRemark(), ""));
|
|
||||||
consStockFlowService.saveFlow(entity);
|
|
||||||
consInfo.setStockNumber(entity.getAfterNumber());
|
|
||||||
UpdateChain.of(ConsInfo.class)
|
|
||||||
.set(ConsInfo::getStockNumber, consInfo.getStockNumber())
|
|
||||||
.eq(ConsInfo::getId, consInfo.getConsInfoId())
|
|
||||||
.update();
|
|
||||||
}
|
}
|
||||||
|
// 记录商品库存流水
|
||||||
|
ProductStockFlow flow = new ProductStockFlow();
|
||||||
|
flow.setCreateUserId(createUserId);
|
||||||
|
flow.setCreateUserName(createUserName);
|
||||||
|
flow.setShopId(shopId);
|
||||||
|
flow.setProductId(product.getId());
|
||||||
|
flow.setProductName(product.getName());
|
||||||
|
// flow.setBeforeNumber(NumberUtil.toBigDecimal(stockNumber));
|
||||||
|
flow.setInOutNumber(NumberUtil.sub(BigDecimal.ZERO, NumberUtil.toBigDecimal(param.getNumber())));
|
||||||
|
// flow.setAfterNumber(NumberUtil.toBigDecimal(product.getStockNumber()));
|
||||||
|
flow.setInOutType(InOutTypeEnum.OUT.value());
|
||||||
|
flow.setInOutItem(InOutItemEnum.DAMAGE_OUT.value());
|
||||||
|
flow.setImgUrls(JSON.toJSONString(param.getImgUrls()));
|
||||||
|
productStockFlowService.save(flow);
|
||||||
|
List<ProductStockVO> productStockList = new ArrayList<>();
|
||||||
|
productStockList.add(new ProductStockVO(param.getProductId(), BigDecimal.valueOf(param.getNumber())));
|
||||||
|
consStockByProduct(InOutTypeEnum.OUT, InOutItemEnum.DAMAGE_OUT, productStockList, null, "【商品报损,自动报损相关耗材】");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -753,6 +743,67 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<ProductStockFlow> findProductStockFlowPage(ProductStockFlowParam param) {
|
||||||
|
Long shopId = StpKit.USER.getShopId(0L);
|
||||||
|
param.setShopId(shopId);
|
||||||
|
param.setProductId(param.getProductId());
|
||||||
|
PageHelper.startPage(PageUtil.buildPageHelp());
|
||||||
|
if (InOutItemEnum.ORDER_IN.value().equals(param.getInOutItem())) {
|
||||||
|
param.setInOutType(InOutTypeEnum.OUT.value());
|
||||||
|
param.setInOutItem(InOutItemEnum.ORDER_OUT.value());
|
||||||
|
param.setIsGreaterZero(SystemConstants.OneZero.ONE);
|
||||||
|
}
|
||||||
|
return PageUtil.convert(new PageInfo<>(productStockFlowMapper.getProductStockFlowList(param)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void consStockByProduct(InOutTypeEnum type, InOutItemEnum item, List<ProductStockVO> products, Long orderId, String remark) {
|
||||||
|
if (CollUtil.isEmpty(products)) return;
|
||||||
|
for (ProductStockVO product : products) {
|
||||||
|
List<ProdConsRelationDTO> consList = prodConsRelationService.selectListByProdId(product.productId());
|
||||||
|
if (CollUtil.isEmpty(consList)) return;
|
||||||
|
for (ProdConsRelationDTO consInfo : consList) {
|
||||||
|
BigDecimal surplusStock = consInfo.getSurplusStock();
|
||||||
|
if (surplusStock == null || surplusStock.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
surplusStock = NumberUtil.mul(surplusStock, product.number());
|
||||||
|
BigDecimal beforeNumber = consInfo.getStockNumber();
|
||||||
|
if (InOutTypeEnum.IN.equals(type)) {
|
||||||
|
consInfo.setStockNumber(NumberUtil.add(beforeNumber, surplusStock));
|
||||||
|
} else {
|
||||||
|
consInfo.setStockNumber(NumberUtil.sub(beforeNumber, surplusStock));
|
||||||
|
}
|
||||||
|
// 更新耗材库存数量
|
||||||
|
ConsInfo consInfoUp = new ConsInfo();
|
||||||
|
consInfoUp.setStockNumber(consInfo.getStockNumber());
|
||||||
|
consInfoMapper.updateByQuery(consInfoUp, query().eq(ConsInfo::getId, consInfo.getConsInfoId()).eq(ConsInfo::getShopId, consInfo.getShopId()));
|
||||||
|
ConsStockFlow flow = new ConsStockFlow();
|
||||||
|
flow.setInOutType(type.value());
|
||||||
|
flow.setInOutItem(item.value());
|
||||||
|
flow.setShopId(consInfo.getShopId());
|
||||||
|
flow.setInOutDate(LocalDate.now());
|
||||||
|
flow.setConId(consInfo.getConsInfoId());
|
||||||
|
flow.setConName(consInfo.getConName());
|
||||||
|
flow.setUnitName(consInfo.getConUnit());
|
||||||
|
flow.setBeforeNumber(beforeNumber);
|
||||||
|
flow.setInOutNumber(surplusStock);
|
||||||
|
flow.setAfterNumber(consInfo.getStockNumber());
|
||||||
|
flow.setPurchasePrice(consInfo.getPrice());
|
||||||
|
flow.setSubTotal(BigDecimal.ZERO);
|
||||||
|
if (flow.getPurchasePrice() != null && flow.getPurchasePrice().compareTo(BigDecimal.ZERO) > 0) {
|
||||||
|
flow.setSubTotal(NumberUtil.mul(surplusStock, flow.getPurchasePrice()));
|
||||||
|
}
|
||||||
|
flow.setProductId(product.productId());
|
||||||
|
flow.setOrderId(orderId);
|
||||||
|
flow.setRemark(remark);
|
||||||
|
consStockFlowService.save(flow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<RelatedProductDTO> getRelateProductList(String relatedProduct) {
|
private List<RelatedProductDTO> getRelateProductList(String relatedProduct) {
|
||||||
if (StrUtil.isNotBlank(relatedProduct) && !"[]".equals(relatedProduct)) {
|
if (StrUtil.isNotBlank(relatedProduct) && !"[]".equals(relatedProduct)) {
|
||||||
List<Long> idList = JSONArray.parseArray(relatedProduct, Long.class);
|
List<Long> idList = JSONArray.parseArray(relatedProduct, Long.class);
|
||||||
|
|||||||
@@ -245,24 +245,4 @@ public class UProductServiceImpl extends ServiceImpl<ProductMapper, Product> imp
|
|||||||
DayOfWeek dayOfWeek = currentDate.getDayOfWeek();
|
DayOfWeek dayOfWeek = currentDate.getDayOfWeek();
|
||||||
return dayOfWeek.getDisplayName(TextStyle.FULL, Locale.ENGLISH);
|
return dayOfWeek.getDisplayName(TextStyle.FULL, Locale.ENGLISH);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
LocalTime startTime = LocalTime.of(17, 0, 0);
|
|
||||||
LocalTime endTime = LocalTime.of(23, 0, 0);
|
|
||||||
LocalTime now = LocalTime.now().withNano(0);
|
|
||||||
|
|
||||||
if (startTime.isBefore(endTime)) {
|
|
||||||
if (now.isAfter(startTime) && now.isBefore(endTime)) {
|
|
||||||
System.out.println("在");
|
|
||||||
} else {
|
|
||||||
System.out.println("不在");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (now.isAfter(startTime) || now.isBefore(endTime)) {
|
|
||||||
System.out.println("在");
|
|
||||||
} else {
|
|
||||||
System.out.println("不在");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
t2.stock_number,
|
t2.stock_number,
|
||||||
t1.surplus_stock
|
t1.surplus_stock
|
||||||
FROM tb_prod_cons_relation t1
|
FROM tb_prod_cons_relation t1
|
||||||
LEFT JOIN tb_cons_info t2 on t1.cons_info_id = t2.id
|
inner JOIN tb_cons_info t2 on t1.cons_info_id = t2.id
|
||||||
WHERE t1.product_id = #{prodId}
|
WHERE t1.product_id = #{prodId}
|
||||||
</select>
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
Reference in New Issue
Block a user