parent
279057d54f
commit
a16b2925b2
|
|
@ -0,0 +1,30 @@
|
|||
package cn.ysk.cashier.config;
|
||||
|
||||
import org.springframework.amqp.core.Binding;
|
||||
import org.springframework.amqp.core.BindingBuilder;
|
||||
import org.springframework.amqp.core.DirectExchange;
|
||||
import org.springframework.amqp.core.Queue;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class RabbitConfig {
|
||||
public static final String QUEUE_STOCK_RECORD_SALE = "queue.stock.record.sale";
|
||||
public static final String EXCHANGE_STOCK_RECORD = "exchange.stock.record";
|
||||
public static final String ROUTING_STOCK_RECORD_SALE = "routing.stock.record.sale";
|
||||
|
||||
@Bean
|
||||
Queue stockRecordSaleQueue() {
|
||||
return new Queue(QUEUE_STOCK_RECORD_SALE);
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectExchange stockRecordExchange() {
|
||||
return new DirectExchange(EXCHANGE_STOCK_RECORD);
|
||||
}
|
||||
|
||||
@Bean
|
||||
Binding binding(Queue stockRecordSaleQueue, DirectExchange stockRecordExchange) {
|
||||
return BindingBuilder.bind(stockRecordSaleQueue).to(stockRecordExchange).with(ROUTING_STOCK_RECORD_SALE);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package cn.ysk.cashier.controller.product;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.ysk.cashier.annotation.AnonymousAccess;
|
||||
import cn.ysk.cashier.annotation.Log;
|
||||
import cn.ysk.cashier.annotation.rest.AnonymousPostMapping;
|
||||
import cn.ysk.cashier.dto.product.StockQueryDto;
|
||||
|
|
@ -112,6 +113,18 @@ public class StockController {
|
|||
return new ResponseEntity<>(dataMap, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@AnonymousAccess
|
||||
@PutMapping("/grounding")
|
||||
@ApiOperation("上下架商品")
|
||||
public ResponseEntity<Object> grounding(
|
||||
@RequestParam Integer shopId,
|
||||
@RequestParam Integer skuId,
|
||||
@RequestParam Boolean isGrounding
|
||||
){
|
||||
stockService.grounding(shopId,skuId, isGrounding);
|
||||
return ResponseEntity.ok("success");
|
||||
}
|
||||
|
||||
@GetMapping("/sku")
|
||||
@ApiOperation("查询库存")
|
||||
public ResponseEntity<Object> queryProductSku(String productId){
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package cn.ysk.cashier.controller.product;
|
||||
|
||||
import cn.ysk.cashier.annotation.AnonymousAccess;
|
||||
import cn.ysk.cashier.annotation.Log;
|
||||
import cn.ysk.cashier.pojo.product.TbProductStockDetail;
|
||||
import cn.ysk.cashier.service.product.TbProductStockDetailService;
|
||||
|
|
|
|||
|
|
@ -127,6 +127,10 @@ public class TbProductSku implements Serializable {
|
|||
@ApiModelProperty(value = "是否暂停销售")
|
||||
private Integer isPauseSale = 0;
|
||||
|
||||
@Column(name = "`is_grounding`")
|
||||
@ApiModelProperty(value = "是否上架")
|
||||
private Integer isGrounding = 0;
|
||||
|
||||
public void setIsDel(Integer isDel) {
|
||||
if(isDel!=null){
|
||||
this.isDel = isDel;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
package cn.ysk.cashier.rabbit;
|
||||
|
||||
import cn.ysk.cashier.config.RabbitConfig;
|
||||
import cn.ysk.cashier.pojo.product.TbProductStockDetail;
|
||||
import cn.ysk.cashier.service.product.TbProductStockDetailService;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class StockListener {
|
||||
|
||||
private final TbProductStockDetailService productStockDetailService;
|
||||
|
||||
public StockListener(TbProductStockDetailService productStockDetailService) {
|
||||
this.productStockDetailService = productStockDetailService;
|
||||
}
|
||||
|
||||
@RabbitListener(queues = RabbitConfig.QUEUE_STOCK_RECORD_SALE)
|
||||
public void recordSaleHandler(String message) {
|
||||
log.info("接收到下单保存库存信息mq消息,消息内容: {}", message);
|
||||
JSONObject jsonObject = JSONObject.parseObject(message);
|
||||
if (!jsonObject.containsKey("orderId")) {
|
||||
log.info("mq消息体有误,确实orderId");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
productStockDetailService.addSaleRecord(jsonObject.getInteger("orderId"));
|
||||
}catch (Exception e) {
|
||||
log.error("执行保存库存mq失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package cn.ysk.cashier.repository.order;
|
|||
|
||||
import cn.ysk.cashier.dto.product.StockCountDTO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
|
|
@ -32,4 +33,20 @@ public interface StockCountRepository extends JpaRepository<StockCountDTO, Integ
|
|||
"info.product_id ",nativeQuery = true)
|
||||
List<StockCountDTO> countStock( @Param("startTime") String startTime, @Param("endTime") String endTime);
|
||||
|
||||
@Query(value = "SELECT pro.shop_id as shop_id, pro.id as pro_id, info.product_name as pro_name, pro.is_stock," +
|
||||
" info.product_sku_name as sku_name, unit.NAME as unit_name ," +
|
||||
"SUM( CASE WHEN orders.order_type != 'return' THEN info.num ELSE 0 END )- SUM( CASE WHEN orders.order_type = 'return' THEN info.num ELSE 0 END ) as stock_count," +
|
||||
"CASE WHEN pro.is_distribute = '0' THEN sku.stock_number ELSE pro.stock_number END AS stock_number " +
|
||||
"FROM " +
|
||||
"tb_order_info orders " +
|
||||
"LEFT JOIN tb_order_detail info ON orders.id = info.order_id " +
|
||||
"LEFT JOIN tb_product pro ON info.product_id = pro.id " +
|
||||
"LEFT JOIN (SELECT product_id,sum(stock_number) as stock_number from tb_product_sku GROUP BY product_id) sku ON info.product_id = sku.product_id " +
|
||||
"LEFT JOIN tb_shop_unit unit ON unit.id = pro.unit_id " +
|
||||
"WHERE " +
|
||||
"orders.id = :orderId " +
|
||||
"AND ( info.STATUS = 'closed' OR info.STATUS = 'refund' ) " +
|
||||
"GROUP BY " +
|
||||
"info.product_id ",nativeQuery = true)
|
||||
List<StockCountDTO> countStockById(Integer orderId);
|
||||
}
|
||||
|
|
@ -55,4 +55,7 @@ public interface TbProductRepository extends JpaRepository<TbProduct, Integer>,
|
|||
@Modifying
|
||||
@Query("update TbProduct set stockNumber=stockNumber+:num where id=:id")
|
||||
void incrStock(@Param("id") Integer id, @Param("num") Integer num);
|
||||
|
||||
@Query("select product from TbProduct product where product.id=:id and product.shopId=:shopId")
|
||||
TbProduct selectByShopIdAndId(Integer id, String shopId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package cn.ysk.cashier.repository.product;
|
|||
import cn.ysk.cashier.pojo.product.TbProductSku;
|
||||
import cn.ysk.cashier.vo.StockV2Vo;
|
||||
import cn.ysk.cashier.vo.StockVo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
|
@ -10,7 +11,6 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
|||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
import java.math.BigDecimal;
|
||||
|
|
@ -170,4 +170,14 @@ public interface TbProductSkuRepository extends JpaRepository<TbProductSku, Inte
|
|||
@Modifying
|
||||
@Query("update TbProductSku set stockNumber=stockNumber+:num where id=:productId")
|
||||
void incrStock(@Param("productId") Integer productId, @Param("num") Double num);
|
||||
|
||||
@Transactional
|
||||
@Modifying
|
||||
@Query("update TbProductSku set isGrounding=:isGrounding where productId=:productId")
|
||||
void updateGroundingByProId(@Param("productId") String productId, @Param("isGrounding") Integer isGrounding);
|
||||
|
||||
@Transactional
|
||||
@Modifying
|
||||
@Query("update TbProductSku set isGrounding=:isGrounding where id=:skuId")
|
||||
void updateGrounding(Integer skuId,int isGrounding);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@ import cn.ysk.cashier.dto.product.OutAndOnDto;
|
|||
import cn.ysk.cashier.dto.product.StockQueryDto;
|
||||
import cn.ysk.cashier.dto.product.TbProductDto;
|
||||
import cn.ysk.cashier.exception.BadRequestException;
|
||||
import cn.ysk.cashier.pojo.product.TbProduct;
|
||||
import cn.ysk.cashier.pojo.product.TbProductSku;
|
||||
import cn.ysk.cashier.pojo.product.TbProductStockDetail;
|
||||
import cn.ysk.cashier.pojo.shop.TbShopInfo;
|
||||
import cn.ysk.cashier.pojo.shop.TbShopUnit;
|
||||
import cn.ysk.cashier.repository.product.TbProductRepository;
|
||||
import cn.ysk.cashier.repository.product.TbProductSkuRepository;
|
||||
import cn.ysk.cashier.repository.product.TbProductStockDetailRepository;
|
||||
import cn.ysk.cashier.repository.shop.TbShopInfoRepository;
|
||||
|
|
@ -15,7 +17,6 @@ import cn.ysk.cashier.repository.shop.TbShopUnitRepository;
|
|||
import cn.ysk.cashier.service.TbProductStockOperateService;
|
||||
import cn.ysk.cashier.service.product.StockService;
|
||||
import cn.ysk.cashier.service.product.TbProductService;
|
||||
import cn.ysk.cashier.service.product.TbProductStockDetailService;
|
||||
import cn.ysk.cashier.utils.CacheKey;
|
||||
import cn.ysk.cashier.utils.FileUtil;
|
||||
import cn.ysk.cashier.utils.RedisUtils;
|
||||
|
|
@ -60,6 +61,7 @@ public class StockServiceImpl implements StockService {
|
|||
private final TbShopInfoRepository tbShopInfoRepository;
|
||||
private final TbShopUnitRepository shopUnitRepository;
|
||||
private final TbProductStockDetailRepository tbProductStockDetailRepository;
|
||||
private final TbProductRepository tbProductRepository;
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
|
|
@ -384,4 +386,19 @@ public class StockServiceImpl implements StockService {
|
|||
}
|
||||
tbProductSkuRepository.updateWarnLineByShopId(stockUpdateWarnLineVO.getWarnLine(), stockUpdateWarnLineVO.getShopId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grounding(Integer shopId, Integer skuId, Boolean isGrounding) {
|
||||
TbProductSku tbProductSku = skuRepository.findById(skuId).orElse(null);
|
||||
if (tbProductSku == null) {
|
||||
throw new BadRequestException("商品不存在,skuId: " + skuId);
|
||||
}
|
||||
TbProduct product = tbProductRepository.selectByShopIdAndId(Integer.parseInt(tbProductSku.getProductId()), String.valueOf(shopId));
|
||||
// 共享库存下架所有sku
|
||||
if (product.getIsDistribute().equals(1)) {
|
||||
tbProductSkuRepository.updateGroundingByProId(product.getId().toString(), isGrounding ? 1 : 0);
|
||||
}else {
|
||||
tbProductSkuRepository.updateGrounding(skuId, isGrounding ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,27 +15,31 @@
|
|||
*/
|
||||
package cn.ysk.cashier.service.impl.productimpl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.ysk.cashier.dto.product.StockCountDTO;
|
||||
import cn.ysk.cashier.pojo.order.TbOrderInfo;
|
||||
import cn.ysk.cashier.pojo.product.TbProductStockDetail;
|
||||
import cn.ysk.cashier.utils.ValidationUtil;
|
||||
import cn.ysk.cashier.utils.FileUtil;
|
||||
import cn.ysk.cashier.repository.order.StockCountRepository;
|
||||
import cn.ysk.cashier.repository.order.TbOrderInfoRepository;
|
||||
import cn.ysk.cashier.utils.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import cn.ysk.cashier.repository.product.TbProductStockDetailRepository;
|
||||
import cn.ysk.cashier.service.product.TbProductStockDetailService;
|
||||
import cn.ysk.cashier.dto.product.TbProductStockDetailDto;
|
||||
import cn.ysk.cashier.dto.product.TbProductStockDetailQueryCriteria;
|
||||
import cn.ysk.cashier.mapper.product.TbProductStockDetailMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import cn.ysk.cashier.utils.PageUtil;
|
||||
import cn.ysk.cashier.utils.QueryHelp;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
|
|
@ -46,11 +50,17 @@ import javax.servlet.http.HttpServletResponse;
|
|||
**/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class TbProductStockDetailServiceImpl implements TbProductStockDetailService {
|
||||
|
||||
private final TbProductStockDetailRepository tbProductStockDetailRepository;
|
||||
private final TbProductStockDetailMapper tbProductStockDetailMapper;
|
||||
|
||||
private final StockCountRepository stockCountRepository;
|
||||
private final EntityManager entityManager;
|
||||
private final TbOrderInfoRepository tbOrderInfoRepository;
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String,Object> queryAll(TbProductStockDetailQueryCriteria criteria, Pageable pageable){
|
||||
Page<TbProductStockDetail> page = tbProductStockDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
|
||||
|
|
@ -66,10 +76,23 @@ public class TbProductStockDetailServiceImpl implements TbProductStockDetailServ
|
|||
Page<TbProductStockDetail> page = tbProductStockDetailRepository.findAll((root, criteriaQuery, criteriaBuilder)
|
||||
-> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
|
||||
Page<TbProductStockDetailDto> map = page.map(tbProductStockDetailMapper::toDto);
|
||||
|
||||
ArrayList<Map<String, Object>> contents = new ArrayList<>();
|
||||
for (TbProductStockDetailDto tbProductStockDetailDto : map.getContent()) {
|
||||
if (StrUtil.isNotBlank(tbProductStockDetailDto.getOrderId())) {
|
||||
TbOrderInfo tbOrderInfo = tbOrderInfoRepository.findById(Integer.valueOf(tbProductStockDetailDto.getOrderId())).orElse(null);
|
||||
Map<String, Object> map1 = BeanUtil.transBean2Map(tbProductStockDetailDto);
|
||||
if (tbOrderInfo != null) {
|
||||
map1.put("orderNo", tbOrderInfo.getOrderNo());
|
||||
}
|
||||
contents.add(map1);
|
||||
}
|
||||
tbProductStockDetailDto.setTypes();
|
||||
}
|
||||
return PageUtil.toPage(map);
|
||||
Map<String,Object> info = new LinkedHashMap<>(2);
|
||||
info.put("content",contents);
|
||||
info.put("totalElements",page.getTotalElements());
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -152,4 +175,33 @@ public class TbProductStockDetailServiceImpl implements TbProductStockDetailServ
|
|||
}
|
||||
FileUtil.downloadExcel(list, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSaleRecord(Integer orderId) {
|
||||
List<StockCountDTO> stockCountDTOS = stockCountRepository.countStockById(orderId);
|
||||
log.info("查询到订单id: {}的所有库存数据: {}", orderId, stockCountDTOS);
|
||||
stockCountDTOS.forEach(s->{
|
||||
if (s.getStockCount() > 0) {
|
||||
TbProductStockDetail productStockDetail = new TbProductStockDetail();
|
||||
productStockDetail.setCreatedAt(System.currentTimeMillis());
|
||||
productStockDetail.setUpdatedAt(System.currentTimeMillis());
|
||||
productStockDetail.setShopId(s.getShopId());
|
||||
productStockDetail.setProductId(s.getProId().toString());
|
||||
productStockDetail.setProductName(s.getProName());
|
||||
productStockDetail.setOrderId(orderId.toString());
|
||||
// productStockDetail.setSkuId(s.getSkuId().toString());
|
||||
productStockDetail.setIsStock(s.getIsStock());//是否开启库存
|
||||
productStockDetail.setLeftNumber(s.getStockNumber()+s.getStockCount());//原库存
|
||||
// productStockDetail.setSpecSnap(s.getSkuName());
|
||||
productStockDetail.setUnitName(s.getUnitName());
|
||||
productStockDetail.setStockNumber(-Double.valueOf(s.getStockCount()));
|
||||
productStockDetail.setSourcePath("NORMAL");
|
||||
productStockDetail.setType("售出记录");
|
||||
productStockDetail.setRemark("售出记录:" + orderId);
|
||||
productStockDetail.setSubType(-1);
|
||||
tbProductStockDetailRepository.save(productStockDetail);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -44,4 +44,13 @@ public interface StockService {
|
|||
* @param stockUpdateWarnLineVO 警戒线
|
||||
*/
|
||||
void updateProductWarnLine(StockUpdateWarnLineVO stockUpdateWarnLineVO);
|
||||
|
||||
/**
|
||||
* 上下架商品
|
||||
*
|
||||
* @param shopId 店铺id
|
||||
* @param skuId ski
|
||||
* @param isGrounding
|
||||
*/
|
||||
void grounding(Integer shopId, Integer skuId, Boolean isGrounding);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,4 +86,6 @@ public interface TbProductStockDetailService {
|
|||
* @throws IOException /
|
||||
*/
|
||||
void download(List<TbProductStockDetailDto> all, HttpServletResponse response) throws IOException;
|
||||
|
||||
void addSaleRecord(Integer orderId);
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package cn.ysk.cashier.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Utils {
|
||||
private static final Logger log = LoggerFactory.getLogger(Utils.class);
|
||||
|
||||
public static <T> void catchErrNoReturn(Supplier<T> supplier) {
|
||||
try {
|
||||
supplier.get();
|
||||
}catch (Exception e) {
|
||||
log.error("执行方法出现异常", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue