tb_product

删除 库存警戒线 库存开关 库存数量
新增 是否自动售罄 标识
tb_shop_prod_category
新增 refund_mode 退菜是否退库存
tb_shop_config 新增 refund_mode 退菜退库存模式

删除 扣除库存模式
This commit is contained in:
2026-04-09 15:54:14 +08:00
parent fa33586aae
commit 4116f7cc0d
31 changed files with 62 additions and 841 deletions

View File

@@ -11,7 +11,6 @@ import com.czg.log.annotation.OperationLog;
import com.czg.product.dto.ProdConsBindDTO;
import com.czg.product.dto.ProdSkuDTO;
import com.czg.product.dto.ProductDTO;
import com.czg.product.entity.ProductStockFlow;
import com.czg.product.param.*;
import com.czg.product.service.ProdConsRelationService;
import com.czg.product.service.ProductService;
@@ -72,12 +71,6 @@ public class ProductController {
public CzgResult<Map<String, Object>> getProductPage(ProductDTO param) {
Page<ProductDTO> data = productService.getProductPage(param);
Map<String, Object> map = JSONObject.parseObject(JSONObject.toJSONString(data), Map.class);
if (data.getRecords() != null && !data.getRecords().isEmpty()) {
ProductDTO first = data.getRecords().getFirst();
map.put("warnLine", first.getWarnLine());
} else {
map.put("warnLine", 0);
}
return CzgResult.success(map);
}
@@ -99,7 +92,6 @@ public class ProductController {
Long shopId = StpKit.USER.getShopId();
param.setShopId(shopId);
List<ProductDTO> productList = productService.getProductCacheList(param);
productService.refreshProductStock(param, productList);
productList.forEach(prod -> prod.setIsSaleTime(uProductService.calcIsSaleTime(prod.getDays(), prod.getStartTime(), prod.getEndTime())));
return CzgResult.success(productList);
}
@@ -150,10 +142,6 @@ public class ProductController {
if (dto.getGroupCategoryId() != null) {
StpKit.USER.checkStaffPermission("yun_xu_xiu_gai_fen_zu");
}
if (dto.getStockNumber() != null) {
StpKit.USER.checkStaffPermission("yun_xu_xiu_gai_shang_pin_ku_cun");
}
Long shopId = StpKit.USER.getShopId();
dto.setShopId(shopId);
productService.updateProduct(dto);
@@ -162,18 +150,6 @@ public class ProductController {
return CzgResult.success();
}
@PostMapping("modifyStock")
@OperationLog("商品-修改库存")
//@SaStaffCheckPermission("yun_xu_xiu_gai_shang_pin")
public CzgResult<Void> updateProductStock(@RequestBody ProductModifyStockParam param) {
ValidatorUtil.validateEntity(param, DefaultGroup.class);
Long shopId = StpKit.USER.getShopId();
param.setShopId(shopId);
productService.updateProductStock(param);
ThreadUtil.execAsync(() -> rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)));
return CzgResult.success();
}
/**
* 商品-删除
*
@@ -236,7 +212,7 @@ public class ProductController {
}
/**
* 商品-退款退至库存
* 商品-退款退至库存 开关
*/
@PostMapping("refundToStock")
@OperationLog("商品-退款退至库存")
@@ -247,29 +223,13 @@ public class ProductController {
return CzgResult.success();
}
/**
* 商品-库存预警设置
*/
@PostMapping("stockWarning")
@OperationLog("商品-库存预警设置")
//@SaAdminCheckPermission("product:stockWarning")
public CzgResult<Void> stockWarning(@RequestParam Integer warnLine) {
AssertUtil.isNull(warnLine, "{}不能为空", "warnLine");
if (warnLine < 0) {
throw new CzgException("预警值不能小于0");
}
productService.stockWarning(warnLine);
return CzgResult.success();
}
/**
* 商品-报损
*/
@PostMapping("reportDamage")
@OperationLog("商品-报损")
//@SaStaffCheckPermission("yun_xu_ti_jiao_bao_sun")
//@SaAdminCheckPermission("product:reportDamage")
public CzgResult<Void> reportDamage(@RequestBody ProductReportDamageParam param) {
//TODO 报损功能
ValidatorUtil.validateEntity(param, DefaultGroup.class);
productService.reportDamage(param);
return CzgResult.success();
@@ -288,17 +248,6 @@ public class ProductController {
return CzgResult.success(data);
}
/**
* 商品-库存变动记录
*/
@GetMapping("stockFlow")
@OperationLog("商品-库存变动记录")
//@SaAdminCheckPermission("consStockFlow:flow")
public CzgResult<Page<ProductStockFlow>> stockFlow(ProductStockFlowParam param) {
Page<ProductStockFlow> data = productService.findProductStockFlowPage(param);
return CzgResult.success(data);
}
/**
* 商品-报损
*/

View File

@@ -19,7 +19,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
/**
@@ -44,7 +43,6 @@ public class UProductController {
list.forEach(prod -> {
prod.setIsSaleTime(uProductService.calcIsSaleTime(prod.getDays(), prod.getStartTime(), prod.getEndTime()));
});
uProductService.refreshProductStock(shopId, list);
return CzgResult.success(list);
}
@@ -55,9 +53,7 @@ public class UProductController {
public CzgResult<List<ShopGroupProductVo>> queryGroupProductList() {
Long shopId = StpKit.USER.getShopId(0L);
List<ShopGroupProductVo> list = uProductService.queryGroupProductList(shopId);
Map<Long, Integer> productStock = uProductService.findShopProductStock(shopId);
list.forEach(item -> {
uProductService.refreshProductStock(productStock, item.getProductList());
item.getProductList().forEach(prod -> {
prod.setIsSaleTime(uProductService.calcIsSaleTime(prod.getDays(), prod.getStartTime(), prod.getEndTime()));
prod.setIsSaleTime(uProductService.calcIsSaleTime(prod.getIsSaleTime(), item.getUseTime(), item.getSaleStartTime(), item.getSaleEndTime()));

View File

@@ -1,89 +0,0 @@
package com.czg.account.dto;
import java.io.Serializable;
import java.time.LocalDateTime;
import com.alibaba.fastjson2.annotation.JSONField;
import java.io.Serial;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 商品分类 实体类。
*
* @author zs
* @since 2025-02-20
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ShopProdCategoryDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
private Long id;
/**
* 分类名称
*/
private String name;
/**
* 简称
*/
private String shortName;
/**
* 上级分类id-为0则表示是顶级
*/
private Long pid;
/**
* 图标
*/
private String pic;
/**
* 店铺Id
*/
private Long shopId;
/**
* 分类描述
*/
private String detail;
/**
* 排序
*/
private Integer sort;
/**
* 关键词
*/
private String keyWord;
/**
* 状态 0-禁用 1-启用
*/
private Integer status;
/**
* 创建时间
*/
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
/**
* 更新时间
*/
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
}

View File

@@ -288,6 +288,10 @@ public class ShopInfoEditDTO {
* 数签子
*/
private Integer isCountStick;
/**
* 退菜退库存模式 1跟随商品分类 2 跟随单商品
*/
private Integer refundMode;
/**
* 企业id

View File

@@ -135,6 +135,10 @@ public class ShopConfig implements Serializable {
* 数签子
*/
private Integer isCountStick;
/**
* 退菜退库存模式 1跟随商品分类 2 跟随单商品
*/
private Integer refundMode;
private String dingAppKey;

View File

@@ -361,6 +361,11 @@ public class ShopInfo implements Serializable {
*/
@Column(ignore = true)
private Integer isCountStick;
/**
* 退菜退库存模式 1跟随商品分类 2 跟随单商品
*/
@Column(ignore = true)
private Integer refundMode;
/**
* 运营端余额

View File

@@ -1,95 +0,0 @@
package com.czg.account.entity;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.io.Serial;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 商品分类 实体类。
*
* @author zs
* @since 2025-02-20
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table("tb_shop_prod_category")
public class ShopProdCategory implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
@Id(keyType = KeyType.Auto)
private Long id;
/**
* 分类名称
*/
private String name;
/**
* 简称
*/
private String shortName;
/**
* 上级分类id-为0则表示是顶级
*/
private Long pid;
/**
* 图标
*/
private String pic;
/**
* 店铺Id
*/
private Long shopId;
/**
* 分类描述
*/
private String detail;
/**
* 排序
*/
private Integer sort;
/**
* 关键词
*/
private String keyWord;
/**
* 状态 0-禁用 1-启用
*/
private Integer status;
/**
* 创建时间
*/
@Column(onInsertValue = "now()")
private LocalDateTime createTime;
/**
* 更新时间
*/
@Column(onInsertValue = "now()", onUpdateValue = "now()")
private LocalDateTime updateTime;
}

View File

@@ -1,14 +0,0 @@
package com.czg.account.service;
import com.mybatisflex.core.service.IService;
import com.czg.account.entity.ShopProdCategory;
/**
* 商品分类 服务层。
*
* @author zs
* @since 2025-02-20
*/
public interface ShopProdCategoryService extends IService<ShopProdCategory> {
}

View File

@@ -108,10 +108,6 @@ public class ProductDTO implements Serializable {
* 套餐内容
*/
private Object groupSnap;
/**
* 库存警戒线
*/
private Integer warnLine;
/**
* 称重 价格/千克
*/
@@ -164,14 +160,14 @@ public class ProductDTO implements Serializable {
* 是否售罄
*/
private Integer isSoldStock;
/**
* 是否自动售罄
*/
private Integer isAutoSoldStock;
/**
* 团购卷分类,可有多个分类
*/
private String groupCategoryId;
/**
* 商品级库存数量
*/
private Integer stockNumber;
/**
* 是否上架
*/

View File

@@ -80,4 +80,8 @@ public class ShopProdCategoryDTO implements Serializable {
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
/**
* 退菜是否退库存 1退菜退库存 2仅退菜不退库存 3每次询问-退菜后弹窗提示
*/
private Integer refundMode;
}

View File

@@ -83,10 +83,6 @@ public class Product implements Serializable {
*/
private String groupSnap;
/**
* 库存警戒线
*/
private Integer warnLine;
/**
* 称重 价格/千克
*/
private BigDecimal weight;
@@ -119,9 +115,9 @@ public class Product implements Serializable {
*/
private Integer isHot;
/**
* 是否开启库存
* 是否自动售罄
*/
private Integer isStock;
private Integer isAutoSoldStock;
/**
* 是否售罄
*/
@@ -131,10 +127,6 @@ public class Product implements Serializable {
*/
private String groupCategoryId;
/**
* 商品库存数量
*/
private Integer stockNumber;
/**
* 是否上架
*/
private Integer isSale;

View File

@@ -68,6 +68,10 @@ public class ShopProdCategory implements Serializable {
* 状态 0-禁用 1-启用
*/
private Integer status;
/**
* 退菜是否退库存 1退菜退库存 2仅退菜不退库存 3每次询问-退菜后弹窗提示
*/
private Integer refundMode;
/**
* 创建时间
*/

View File

@@ -1,46 +0,0 @@
package com.czg.product.param;
import com.alibaba.fastjson2.annotation.JSONField;
import com.czg.validator.group.DefaultGroup;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 商品修改库存
*
* @author Tankaikai tankaikai@aliyun.com
* @since 1.0 2025-02-16
*/
@Data
public class ProductModifyStockParam implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
@NotNull(message = "ID不能为空", groups = DefaultGroup.class)
private Long id;
/**
* 库存数量
*/
@NotNull(message = "库存数量不能为空", groups = DefaultGroup.class)
@Min(value = 0, message = "库存数量不能小于0", groups = DefaultGroup.class)
@Max(value = Integer.MAX_VALUE, message = "库存数量不能大于" + Integer.MAX_VALUE, groups = DefaultGroup.class)
private Integer stockNumber;
/**
* 备注
*/
private String remark;
/**
* 店铺id
*/
@JSONField(serialize = false)
private Long shopId;
}

View File

@@ -2,7 +2,6 @@ package com.czg.product.service;
import com.czg.product.dto.ProductDTO;
import com.czg.product.entity.Product;
import com.czg.product.entity.ProductStockFlow;
import com.czg.product.param.*;
import com.czg.product.vo.ProductStatisticsVo;
import com.mybatisflex.core.paginate.Page;
@@ -71,13 +70,6 @@ public interface ProductService extends IService<Product> {
*/
void updateProduct(ProductDTO dto);
/**
* 修改商品库存数量
*
* @param param 商品id及库存数量
*/
void updateProductStock(ProductModifyStockParam param);
/**
* 删除商品
*
@@ -107,12 +99,6 @@ public interface ProductService extends IService<Product> {
*/
void refundToStock(ProdRefundToStockParam param);
/**
* 库存预警
*
* @param warnLine 预警线
*/
void stockWarning(Integer warnLine);
/**
* 商品报损
@@ -127,21 +113,4 @@ public interface ProductService extends IService<Product> {
* @param param 商品统计入参
*/
ProductStatisticsVo getProductStatistics(ProductInfoParam param);
/**
* 商品出入库流水查询
*
* @param param 查询参数
* @return 分页数据
*/
Page<ProductStockFlow> findProductStockFlowPage(ProductStockFlowParam param);
/**
* 刷新商品库存
*
* @param param 查询条件
* @param records 商品数据集合
*/
void refreshProductStock(ProductDTO param, List<ProductDTO> records);
}

View File

@@ -12,5 +12,4 @@ import com.mybatisflex.core.service.IService;
*/
public interface ProductStockFlowService extends IService<ProductStockFlow> {
void saveFlow(ProductStockFlow entity);
}

View File

@@ -10,7 +10,6 @@ import com.mybatisflex.core.service.IService;
import java.time.LocalTime;
import java.util.List;
import java.util.Map;
/**
* 用户端商品Service
@@ -52,28 +51,6 @@ public interface UProductService extends IService<Product> {
*/
ShopProductSkuInfoVo getProductSkuInfo(ShopProductSkuParam param);
/**
* 刷新商品库存
*
* @param shopId 店铺id
*/
Map<Long, Integer> findShopProductStock(Long shopId);
/**
* 刷新商品库存
*
* @param shopId 店铺id
* @param productList 商品列表
*/
void refreshProductStock(Long shopId, List<ShopProductVo> productList);
/**
* 刷新商品库存
*
* @param productStock 商品库存
* @param productList 商品列表
*/
void refreshProductStock(Map<Long, Integer> productStock, List<ShopProductVo> productList);
/**
* 分组计算是否在可售时间内

View File

@@ -67,27 +67,15 @@ public class ShopProductSkuInfoVo implements Serializable {
*/
private BigDecimal realSalesNumber;
/**
* 是否售罄同isSoldStock
*/
private Integer isPauseSale;
/**
* 商品库存
*/
private Integer stockNumber;
/**
* 是否售罄isPauseSale
* 是否售罄
*/
private Integer isSoldStock;
/**
* 是否开启库存
*/
private Integer isAutoSoldStock;
/**
* 是否上架(同isGrounding)
*/
private Integer isSale;
/**
* 是否开启库存
*/
private Integer isStock;
/**
* 是否上架(同isSale)
*/
private Integer isGrounding;
}

View File

@@ -58,10 +58,6 @@ public class ShopProductVo implements Serializable {
* 是否售罄 1-是 0-否
*/
private Integer isSoldStock;
/**
* 库存数量
*/
private Integer stockNumber;
/**
* 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券
*/
@@ -114,8 +110,4 @@ public class ShopProductVo implements Serializable {
* 店铺id
*/
private Long shopId;
/**
* 是否开启库存
*/
private Integer isStock;
}

View File

@@ -1,14 +0,0 @@
package com.czg.service.account.mapper;
import com.mybatisflex.core.BaseMapper;
import com.czg.account.entity.ShopProdCategory;
/**
* 商品分类 映射层。
*
* @author zs
* @since 2025-02-20
*/
public interface ShopProdCategoryMapper extends BaseMapper<ShopProdCategory> {
}

View File

@@ -7,15 +7,16 @@ import com.czg.account.dto.pad.*;
import com.czg.account.entity.PadLayout;
import com.czg.account.entity.PadProductCategory;
import com.czg.account.entity.PadProductCategoryDetail;
import com.czg.account.entity.ShopProdCategory;
import com.czg.account.service.*;
import com.czg.constants.SystemConstants;
import com.czg.exception.CzgException;
import com.czg.product.entity.ProdSku;
import com.czg.product.entity.Product;
import com.czg.product.entity.ShopProdCategory;
import com.czg.product.service.ProdSkuService;
import com.czg.product.service.ProductRpcService;
import com.czg.product.service.ProductService;
import com.czg.product.service.ShopProdCategoryService;
import com.czg.product.vo.ProductVO;
import com.czg.service.account.mapper.PadProductCategoryDetailMapper;
import com.czg.utils.PageUtil;
@@ -50,7 +51,7 @@ public class PadProdServiceImpl implements PadProdService {
private ProductRpcService productRpcService;
@DubboReference
private ProdSkuService prodSkuService;
@Resource
@DubboReference
private ShopProdCategoryService shopProdCategoryService;
@Resource
private PadLayoutService padLayoutService;

View File

@@ -1,18 +0,0 @@
package com.czg.service.account.service.impl;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.czg.account.entity.ShopProdCategory;
import com.czg.account.service.ShopProdCategoryService;
import com.czg.service.account.mapper.ShopProdCategoryMapper;
import org.springframework.stereotype.Service;
/**
* 商品分类 服务层实现。
*
* @author zs
* @since 2025-02-20
*/
@Service
public class ShopProdCategoryServiceImpl extends ServiceImpl<ShopProdCategoryMapper, ShopProdCategory> implements ShopProdCategoryService{
}

View File

@@ -1,7 +0,0 @@
<?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.czg.service.account.mapper.ShopProdCategoryMapper">
</mapper>

View File

@@ -43,7 +43,6 @@ import com.czg.order.enums.PayEnums;
import com.czg.order.service.*;
import com.czg.order.vo.*;
import com.czg.pay.PayNotifyRespDTO;
import com.czg.product.entity.Product;
import com.czg.product.service.ProductRpcService;
import com.czg.product.service.ProductService;
import com.czg.resp.CzgResult;
@@ -1041,14 +1040,15 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
BigDecimal packFee = BigDecimal.ZERO;
for (OrderDetail detail : orderDetails) {
if (!detail.getIsTemporary().equals(1) && detail.getProductId() > 0) {
Product product = productService.getOne(QueryWrapper.create()
.eq(Product::getId, detail.getProductId())
.eq(Product::getShopId, detail.getShopId())
.eq(Product::getIsDel, 0)
.eq(Product::getIsStock, 1));
if (product != null && detail.getNum().compareTo(new BigDecimal(product.getStockNumber())) > 0) {
throw new CzgException("下单失败" + product.getName() + "库存不足");
}
//TODO 库存问题 商品无库存 统一走 耗材
// Product product = productService.getOne(QueryWrapper.create()
// .eq(Product::getId, detail.getProductId())
// .eq(Product::getShopId, detail.getShopId())
// .eq(Product::getIsDel, 0)
// .eq(Product::getIsStock, 1));
// if (product != null && detail.getNum().compareTo(new BigDecimal(product.getStockNumber())) > 0) {
// throw new CzgException("下单失败" + product.getName() + "库存不足");
// }
}
if (detail.getDiscountSaleAmount() != null && detail.getDiscountSaleAmount().compareTo(BigDecimal.ZERO) > 0) {
detail.setUnitPrice(detail.getDiscountSaleAmount());

View File

@@ -12,7 +12,6 @@ import com.mybatisflex.core.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List;
/**
@@ -38,8 +37,6 @@ public interface ProductMapper extends BaseMapper<Product> {
List<RecommendProVO> selectCouponProBySaleNum();
void updateProductStockNum(@Param("id") Long id, @Param("shopId") Long shopId, @Param("type") String type, @Param("num") BigDecimal num);
List<RecommendProVO> selectRecommendProductList(@Param("lng") String lng, @Param("lat") String lat, @Param("address") String address,
@Param("classify") Integer classify, @Param("orderType") Integer orderType,
@Param("distanceType") Integer distanceType, @Param("name") String name);

View File

@@ -5,12 +5,14 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.czg.config.RabbitPublisher;
import com.czg.constants.SystemConstants;
import com.czg.product.dto.ProductStockSubtractDTO;
import com.czg.product.entity.*;
import com.czg.product.entity.ConsInfo;
import com.czg.product.entity.ConsStockFlow;
import com.czg.product.entity.ProdConsRelation;
import com.czg.product.entity.Product;
import com.czg.product.enums.InOutItemEnum;
import com.czg.product.enums.InOutTypeEnum;
import com.czg.product.service.ConsStockFlowService;
@@ -71,37 +73,13 @@ public class ProductRpcServiceImpl implements ProductRpcService {
if (CollUtil.isEmpty(list)) {
return;
}
//TODO 优化耗材库存更新逻辑 耗材预警
boolean isLowWarnLine = false;
for (ProductStockSubtractDTO dto : list) {
Product product = productMapper.selectOneById(dto.getProductId());
if (product == null) {
continue;
}
// 商品开启库存
if (product.getIsStock() == SystemConstants.OneZero.ONE) {
productMapper.updateProductStockNum(dto.getProductId(), dto.getShopId(), "sub", dto.getNum());
// 记录商品库存流水
ProductStockFlow flow = new ProductStockFlow();
flow.setCreateUserId(1L);
flow.setCreateUserName("银收客");
flow.setShopId(shopId);
flow.setProductId(product.getId());
flow.setProductName(product.getName());
flow.setBeforeNumber(NumberUtil.toBigDecimal(product.getStockNumber()));
flow.setInOutNumber(NumberUtil.sub(BigDecimal.ZERO, NumberUtil.toBigDecimal(dto.getNum())));
flow.setAfterNumber(NumberUtil.sub(NumberUtil.toBigDecimal(product.getStockNumber()), NumberUtil.toBigDecimal(dto.getNum())));
flow.setInOutType(InOutTypeEnum.OUT.value());
flow.setInOutItem(InOutItemEnum.ORDER_OUT.value());
flow.setOrderId(orderId);
productStockFlowService.saveFlow(flow);
cleanCategoryProduct(shopId, product.getCategoryId());
refreshRedisProdStock(shopId, product.getId(), flow.getAfterNumber());
Integer warnLine = ObjUtil.defaultIfNull(product.getWarnLine(), 10);
if (!isLowWarnLine && NumberUtil.isLess(flow.getAfterNumber(), Convert.toBigDecimal(warnLine))) {
isLowWarnLine = true;
}
}
// 查询商品绑定耗材信息
List<ProdConsRelation> relationList = prodConsRelationMapper.selectListByQuery(QueryWrapper.create().eq(ProdConsRelation::getProductId, dto.getProductId()));
if (CollUtil.isEmpty(relationList)) {
@@ -161,28 +139,6 @@ public class ProductRpcServiceImpl implements ProductRpcService {
}
boolean isLowWarnLine = false;
for (ProductStockSubtractDTO dto : list) {
Product product = productMapper.selectOneById(dto.getProductId());
productMapper.updateProductStockNum(dto.getProductId(), dto.getShopId(), "add", dto.getNum());
// 记录商品库存流水
ProductStockFlow flow = new ProductStockFlow();
flow.setCreateUserId(1L);
flow.setCreateUserName("银收客");
flow.setShopId(shopId);
flow.setProductId(product.getId());
flow.setProductName(product.getName());
flow.setBeforeNumber(NumberUtil.toBigDecimal(product.getStockNumber()));
flow.setInOutNumber(NumberUtil.toBigDecimal(dto.getNum()));
flow.setAfterNumber(NumberUtil.add(NumberUtil.toBigDecimal(product.getStockNumber()), NumberUtil.toBigDecimal(dto.getNum())));
flow.setInOutType(InOutTypeEnum.OUT.value());
flow.setInOutItem(InOutItemEnum.ORDER_OUT.value());
flow.setRemark("红冲订单取消/退菜/退单消耗的库存");
flow.setOrderId(orderId);
productStockFlowService.saveFlow(flow);
refreshRedisProdStock(shopId, product.getId(), flow.getAfterNumber());
Integer warnLine = ObjUtil.defaultIfNull(product.getWarnLine(), 10);
if (!isLowWarnLine && (NumberUtil.isLessOrEqual(flow.getBeforeNumber(), BigDecimal.ZERO) || NumberUtil.isLess(flow.getAfterNumber(), Convert.toBigDecimal(warnLine)))) {
isLowWarnLine = true;
}
// 查询商品绑定耗材信息
List<ProdConsRelation> relationList = prodConsRelationMapper.selectListByQuery(QueryWrapper.create().eq(ProdConsRelation::getProductId, dto.getProductId()));
if (CollUtil.isEmpty(relationList)) {
@@ -220,7 +176,6 @@ public class ProductRpcServiceImpl implements ProductRpcService {
consStockFlow.setAfterNumber(consInfo.getStockNumber());
consStockFlow.setSubTotal(NumberUtil.mul(surplusStock, consInfo.getPrice()));
consStockFlow.setProductId(dto.getProductId());
//consStockFlow.setSkuId(0L);
consStockFlow.setRemark("红冲订单取消/退菜/退单消耗的库存");
consStockFlow.setOrderId(orderId);
consStockFlowService.saveFlow(consStockFlow);
@@ -241,32 +196,6 @@ public class ProductRpcServiceImpl implements ProductRpcService {
}
boolean isLowWarnLine = false;
for (ProductStockSubtractDTO dto : list) {
Product product = productMapper.selectOneById(dto.getProductId());
// 商品是否允许退款退货时归还库存
if (SystemConstants.OneZero.ONE == product.getIsRefundStock() && SystemConstants.OneZero.ONE == product.getIsStock()) {
productMapper.updateProductStockNum(dto.getProductId(), dto.getShopId(), "add", dto.getNum());
// 记录商品库存流水
ProductStockFlow flow = new ProductStockFlow();
flow.setCreateUserId(1L);
flow.setCreateUserName("银收客");
flow.setShopId(shopId);
flow.setProductId(product.getId());
flow.setProductName(product.getName());
flow.setBeforeNumber(NumberUtil.toBigDecimal(product.getStockNumber()));
flow.setInOutNumber(NumberUtil.toBigDecimal(dto.getNum()));
flow.setAfterNumber(NumberUtil.add(NumberUtil.toBigDecimal(product.getStockNumber()), NumberUtil.toBigDecimal(dto.getNum())));
flow.setInOutType(InOutTypeEnum.OUT.value());
flow.setInOutItem(InOutItemEnum.ORDER_OUT.value());
flow.setRemark("红冲订单取消/退菜/退单消耗的库存");
flow.setOrderId(orderId);
productStockFlowService.saveFlow(flow);
// String key = StrUtil.format(SHOP_PRODUCT_STOCK, shopId, product.getId());
refreshRedisProdStock(shopId, product.getId(), flow.getAfterNumber());
Integer warnLine = ObjUtil.defaultIfNull(product.getWarnLine(), 10);
if (!isLowWarnLine && (NumberUtil.isLessOrEqual(flow.getBeforeNumber(), BigDecimal.ZERO) || NumberUtil.isLess(flow.getAfterNumber(), Convert.toBigDecimal(warnLine)))) {
isLowWarnLine = true;
}
}
// 查询商品绑定耗材信息
List<ProdConsRelation> relationList = prodConsRelationMapper.selectListByQuery(QueryWrapper.create().eq(ProdConsRelation::getProductId, dto.getProductId()));
if (CollUtil.isEmpty(relationList)) {
@@ -304,7 +233,6 @@ public class ProductRpcServiceImpl implements ProductRpcService {
consStockFlow.setAfterNumber(consInfo.getStockNumber());
consStockFlow.setSubTotal(NumberUtil.mul(surplusStock, consInfo.getPrice()));
consStockFlow.setProductId(dto.getProductId());
// consStockFlow.setSkuId(0L);
consStockFlow.setOrderId(orderId);
consStockFlow.setRemark("红冲订单取消/退菜/退单消耗的库存");
consStockFlowService.saveFlow(consStockFlow);

View File

@@ -25,8 +25,6 @@ import com.czg.sa.StpKit;
import com.czg.service.RedisService;
import com.czg.service.product.mapper.*;
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.query.QueryWrapper;
import com.mybatisflex.core.row.DbChain;
@@ -271,7 +269,6 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
.setMemberPrice(getMainSkuMemberPrice(exportDTO))
.setType(exportDTO.getType())
.setGroupType(exportDTO.getGroupType())
.setStockNumber(exportDTO.getStockNumber())
.setIsSale(getMainSkuIsSale(exportDTO))
.setGroupTitleName(proGroupDTO.getTitle())
.setGroupProductNumber(Optional.ofNullable(proGroupDTO.getNumber()).map(String::valueOf).orElse(""))
@@ -510,24 +507,6 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
}
prodSkuMapper.insertBatch(prodSkuList);
}
if (entity.getIsStock() == SystemConstants.OneZero.ZERO) {
return;
}
// 记录商品库存流水
ProductStockFlow flow = new ProductStockFlow();
Long createUserId = StpKit.USER.getLoginIdAsLong();
String createUserName = StpKit.USER.getAccount();
flow.setCreateUserId(createUserId);
flow.setCreateUserName(createUserName);
flow.setShopId(shopId);
flow.setProductId(entity.getId());
flow.setProductName(entity.getName());
flow.setBeforeNumber(BigDecimal.ZERO);
flow.setInOutNumber(NumberUtil.toBigDecimal(entity.getStockNumber()));
flow.setAfterNumber(NumberUtil.toBigDecimal(entity.getStockNumber()));
flow.setInOutType(InOutTypeEnum.IN.value());
flow.setInOutItem(InOutItemEnum.WIN_IN.value());
productStockFlowService.saveFlow(flow);
}
@Override
@@ -561,19 +540,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
}
entity.setRelatedRecommend(dto.getRelatedRecommendStr());
super.updateById(entity);
// 清除商品分类列表缓存
clearProductCache(old.getCategoryId());
if (!old.getCategoryId().equals(dto.getCategoryId())) {
clearProductCache(entity.getCategoryId());
}
if (ObjUtil.defaultIfNull(dto.getIsStock(), old.getIsStock()) == SystemConstants.OneZero.ZERO) {
redisService.del(StrUtil.format(CacheConstant.SHOP_PRODUCT_STOCK, shopId, dto.getId()));
Boolean b = redisService.hasKey(StrUtil.format(CacheConstant.SHOP_PRODUCT_STOCK, shopId, dto.getId()));
log.info("删除商品库存缓存:{}-{}", dto.getId(), b);
} else {
redisService.set(StrUtil.format(CacheConstant.SHOP_PRODUCT_STOCK, shopId, dto.getId()), dto.getStockNumber());
log.info("设置商品库存缓存:{}-{}", dto.getId(), dto.getStockNumber());
}
List<ProdSkuDTO> skuList = dto.getSkuList();
// 商品SKU-ID列表
List<Long> skuIdList = prodSkuMapper.selectListByQueryAs(query().select(ProdSku::getId).eq(ProdSku::getProductId, dto.getId()), Long.class);
@@ -605,85 +572,6 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
.eq(ProdSku::getShopId, shopId)
.update();
}
if (entity.getIsStock() == SystemConstants.OneZero.ZERO) {
return;
}
// 记录商品库存流水
ProductStockFlow flow = new ProductStockFlow();
Long createUserId = StpKit.USER.getLoginIdAsLong();
String createUserName = StpKit.USER.getAccount();
flow.setCreateUserId(createUserId);
flow.setCreateUserName(createUserName);
flow.setShopId(shopId);
flow.setProductId(old.getId());
flow.setProductName(old.getName());
flow.setBeforeNumber(NumberUtil.toBigDecimal(old.getStockNumber()));
BigDecimal inOutNumber = NumberUtil.sub(NumberUtil.toBigDecimal(entity.getStockNumber()), flow.getBeforeNumber());
// 盘亏
if (NumberUtil.isLess(inOutNumber, BigDecimal.ZERO)) {
flow.setInOutNumber(inOutNumber);
flow.setInOutType(InOutTypeEnum.OUT.value());
flow.setInOutItem(InOutItemEnum.LOSS_OUT.value());
}
// 盘盈
if (NumberUtil.isGreater(inOutNumber, BigDecimal.ZERO)) {
flow.setInOutNumber(inOutNumber);
flow.setInOutType(InOutTypeEnum.IN.value());
flow.setInOutItem(InOutItemEnum.WIN_IN.value());
}
// 盘平
if (NumberUtil.equals(inOutNumber, BigDecimal.ZERO)) {
return;
}
flow.setAfterNumber(NumberUtil.toBigDecimal(entity.getStockNumber()));
productStockFlowService.saveFlow(flow);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateProductStock(ProductModifyStockParam param) {
Product entity = super.getById(param.getId());
if (entity.getIsStock() == SystemConstants.OneZero.ZERO) {
throw new CzgException("该商品未开启库存管理,暂不支持修改库存");
}
if (!entity.getShopId().equals(param.getShopId())) {
return;
}
UpdateChain.of(Product.class)
.set(Product::getStockNumber, param.getStockNumber())
.set(Product::getShopId, param.getShopId())
.eq(Product::getId, param.getId())
.update();
// 记录商品库存流水
ProductStockFlow flow = new ProductStockFlow();
Long createUserId = StpKit.USER.getLoginIdAsLong();
String createUserName = StpKit.USER.getAccount();
flow.setCreateUserId(createUserId);
flow.setCreateUserName(createUserName);
flow.setShopId(param.getShopId());
flow.setProductId(entity.getId());
flow.setProductName(entity.getName());
flow.setBeforeNumber(NumberUtil.toBigDecimal(entity.getStockNumber()));
BigDecimal inOutNumber = NumberUtil.sub(NumberUtil.toBigDecimal(param.getStockNumber()), flow.getBeforeNumber());
// 盘亏
if (NumberUtil.isLess(inOutNumber, BigDecimal.ZERO)) {
flow.setInOutNumber(inOutNumber);
flow.setInOutType(InOutTypeEnum.OUT.value());
flow.setInOutItem(InOutItemEnum.LOSS_OUT.value());
}
// 盘盈
if (NumberUtil.isGreater(inOutNumber, BigDecimal.ZERO)) {
flow.setInOutNumber(inOutNumber);
flow.setInOutType(InOutTypeEnum.IN.value());
flow.setInOutItem(InOutItemEnum.WIN_IN.value());
}
// 盘平
if (NumberUtil.equals(inOutNumber, BigDecimal.ZERO)) {
return;
}
flow.setAfterNumber(NumberUtil.toBigDecimal(entity.getStockNumber()));
flow.setRemark(param.getRemark());
productStockFlowService.saveFlow(flow);
}
@Override
@@ -757,12 +645,6 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
.eq(ProdSku::getProductId, id)
.eq(ProdSku::getShopId, shopId)
.update();
}else if("stock".equals(param.getOptType())){
UpdateChain.of(Product.class)
.set(Product::getIsStock, isSale)
.eq(Product::getId, id)
.eq(Product::getShopId, shopId)
.update();
}
Product product = mapper.selectOneById(id);
prodId = product.getId();
@@ -834,14 +716,6 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
super.updateById(entity);
}
@Override
public void stockWarning(Integer warnLine) {
Long shopId = StpKit.USER.getShopId();
UpdateChain.of(Product.class)
.set(Product::getWarnLine, warnLine)
.eq(Product::getShopId, shopId)
.update();
}
@Override
@Transactional(rollbackFor = Exception.class)
@@ -849,34 +723,6 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
Long shopId = StpKit.USER.getShopId();
Long createUserId = StpKit.USER.getLoginIdAsLong();
String createUserName = StpKit.USER.getAccount();
Product product = mapper.selectOneById(param.getProductId());
if (product == null) {
throw new CzgException("商品不存在");
}
if (product.getIsStock() == SystemConstants.OneZero.ZERO) {
throw new CzgException("商品未开启库存不支持报损操作");
}
// 商品现有库存数量
Integer stockNumber = product.getStockNumber();
product.setStockNumber(stockNumber - param.getNumber());
if (product.getStockNumber() < 0) {
throw new CzgException("商品库存不足,无法报损");
}
super.updateById(product);
// 记录商品库存流水
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.saveFlow(flow);
// 如果绑定了耗材,则同步更新耗材库存
List<ProdConsRelationDTO> consList = prodConsRelationMapper.selectListByProdId(param.getProductId());
if (CollUtil.isEmpty(consList)) {
@@ -921,43 +767,6 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
return data;
}
@Override
public Page<ProductStockFlow> findProductStockFlowPage(ProductStockFlowParam param) {
Long shopId = StpKit.USER.getShopId(0L);
param.setShopId(shopId);
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 refreshProductStock(ProductDTO param, List<ProductDTO> records) {
QueryWrapper queryWrapper = buildQueryWrapper(param);
queryWrapper.select(PRODUCT.ID, PRODUCT.STOCK_NUMBER);
List<Product> list = super.list(queryWrapper);
if (CollUtil.isEmpty(list)) {
return;
}
Map<Long, Integer> stock = list.stream().collect(Collectors.toMap(Product::getId, Product::getStockNumber));
records.parallelStream().forEach(record -> {
record.setStockNumber(stock.getOrDefault(record.getId(), 0));
if (record.getIsStock() == SystemConstants.OneZero.ONE) {
refreshRedisStock(record.getShopId(), record.getId(), record.getStockNumber());
} else {
redisService.del(StrUtil.format(CacheConstant.SHOP_PRODUCT_STOCK, record.getShopId(), record.getId()));
}
});
}
private void refreshRedisStock(Long shopId, Long productId, Integer stockNumber) {
String key = StrUtil.format(CacheConstant.SHOP_PRODUCT_STOCK, shopId, productId);
redisService.set(key, stockNumber);
}
private List<RelatedProductDTO> getRelateProductList(String relatedProduct) {
if (StrUtil.isNotBlank(relatedProduct) && !"[]".equals(relatedProduct)) {
List<Long> idList = JSONArray.parseArray(relatedProduct, Long.class);

View File

@@ -1,25 +1,12 @@
package com.czg.service.product.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.czg.product.entity.Product;
import com.czg.product.entity.ProductStockFlow;
import com.czg.product.service.ProductStockFlowService;
import com.czg.service.product.mapper.ConsInfoMapper;
import com.czg.service.product.mapper.ProductMapper;
import com.czg.service.product.mapper.ProductStockFlowMapper;
import com.czg.service.product.util.WxAccountUtil;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.List;
/**
* 商品库存流水服务实现类
*
@@ -30,31 +17,4 @@ import java.util.List;
@Slf4j
public class ProductStockFlowServiceImpl extends ServiceImpl<ProductStockFlowMapper, ProductStockFlow> implements ProductStockFlowService {
@Resource
private ProductMapper productMapper;
@Resource
private ConsInfoMapper consInfoMapper;
@Resource
private WxAccountUtil wxAccountUtil;
@Override
public void saveFlow(ProductStockFlow entity) {
mapper.insert(entity);
Long shopId = entity.getShopId();
BigDecimal afterNumber = entity.getAfterNumber();
Product product = productMapper.selectOneById(entity.getProductId());
String shopName = productMapper.getShopName(shopId);
BigDecimal warnLine = Convert.toBigDecimal(product.getWarnLine());
// 库存小于警告值,发送消息提醒
if (NumberUtil.isLess(afterNumber, warnLine)) {
List<String> openIdList = consInfoMapper.findOpenIdList(shopId, "pro");
if (CollUtil.isEmpty(openIdList)) {
return;
}
String productName = StrUtil.sub(product.getName(), 0, 10).concat("...");
String conName = StrUtil.format("{}数量<预警值{}", productName, warnLine);
ThreadUtil.execAsync(() -> openIdList.parallelStream().forEach(openId ->
wxAccountUtil.sendStockMsg("商品库存预警", shopName, conName, afterNumber, openId)));
}
}
}

View File

@@ -15,12 +15,11 @@ import com.czg.service.product.mapper.ShopProdCategoryMapper;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -30,7 +29,7 @@ import java.util.List;
* @author Tankaikai tankaikai@aliyun.com
* @since 1.0 2025-02-10
*/
@Service
@DubboService
public class ShopProdCategoryServiceImpl extends ServiceImpl<ShopProdCategoryMapper, ShopProdCategory> implements ShopProdCategoryService {
@Resource
@@ -121,22 +120,18 @@ public class ShopProdCategoryServiceImpl extends ServiceImpl<ShopProdCategoryMap
@Override
public void disableShopProdCategory(Long id) {
Long shopId = StpKit.USER.getShopId(0L);
UpdateChain.of(ShopProdCategory.class)
.set(ShopProdCategory::getStatus, SystemConstants.OneZero.ZERO)
.eq(ShopProdCategory::getId, id)
.eq(ShopProdCategory::getShopId, shopId)
.update();
ShopProdCategory prodCategory = new ShopProdCategory();
prodCategory.setStatus(SystemConstants.OneZero.ZERO);
update(prodCategory, query().eq(ShopProdCategory::getId, id).eq(ShopProdCategory::getShopId, shopId));
productService.clearProductCache(id);
}
@Override
public void enableShopProdCategory(Long id) {
Long shopId = StpKit.USER.getShopId(0L);
UpdateChain.of(ShopProdCategory.class)
.set(ShopProdCategory::getStatus,SystemConstants.OneZero.ONE)
.eq(ShopProdCategory::getId, id)
.eq(ShopProdCategory::getShopId, shopId)
.update();
ShopProdCategory prodCategory = new ShopProdCategory();
prodCategory.setStatus(SystemConstants.OneZero.ONE);
update(prodCategory, query().eq(ShopProdCategory::getId, id).eq(ShopProdCategory::getShopId, shopId));
productService.clearProductCache(id);
}

View File

@@ -238,7 +238,7 @@ public class ShopSyncServiceImpl implements ShopSyncService {
unitMap.put(unit.getSyncId(), unit.getId());
}
}
;
buildNotice(mainMapList, "单位同步", pointShopUnits.size(), null, null);
buildNotice(mainMapList, "单位新增", unitMap.size() - pointShopUnits.size(), null, null);
log.info("单位同步,源{}个,已有{}个,同步{}个", list.size(), pointShopUnits.size(), unitMap.size() - pointShopUnits.size());
@@ -546,7 +546,6 @@ public class ShopSyncServiceImpl implements ShopSyncService {
tbProductNew.setCategoryId(tbProduct.getCategoryId() != null ? cateGoryMap.get(tbProduct.getCategoryId()) : null);
tbProductNew.setSpecId(tbProduct.getSpecId() != null ? specMap.get(tbProduct.getSpecId()) : null);
tbProductNew.setUnitId(tbProduct.getUnitId() != null ? unitMap.get(tbProduct.getUnitId()) : null);
tbProductNew.setStockNumber(0);
if (CollUtil.isNotEmpty(pointProducts)) {
tbProductNew.setIsSale(0);
}
@@ -565,9 +564,9 @@ public class ShopSyncServiceImpl implements ShopSyncService {
tbProductNew.setType(tbProduct.getType());
tbProductNew.setGroupType(tbProduct.getGroupType());
tbProductNew.setPackFee(tbProduct.getPackFee());
tbProductNew.setIsAutoSoldStock(tbProduct.getIsAutoSoldStock());
tbProductNew.setCoverImg(tbProduct.getCoverImg());
tbProductNew.setImages(tbProduct.getImages());
tbProductNew.setWarnLine(tbProduct.getWarnLine());
tbProductNew.setWeight(tbProduct.getWeight());
tbProductNew.setSelectSpecInfo(tbProduct.getSelectSpecInfo());
tbProductNew.setSort(tbProduct.getSort());
@@ -655,16 +654,13 @@ public class ShopSyncServiceImpl implements ShopSyncService {
newEntity.setEndTime(null);
newEntity.setDays(null);
newEntity.setIsHot(null);
newEntity.setIsStock(null);
newEntity.setIsSoldStock(null);
newEntity.setStockNumber(null);
newEntity.setIsSale(null);
newEntity.setIsRefundStock(null);
productService.updateById(newEntity);
} else {
newEntity.setId(null);
newEntity.setIsSale(0);
newEntity.setStockNumber(0);
productService.save(newEntity);
}
if (newEntity.getCategoryId() != null) {

View File

@@ -2,7 +2,6 @@ package com.czg.service.product.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
@@ -166,55 +165,11 @@ public class UProductServiceImpl extends ServiceImpl<ProductMapper, Product> imp
, ShopProductSkuInfoVo.class);
// throw new CzgException("商品SKU不可售或不存在");
if (data != null) {
data.setStockNumber(ObjUtil.defaultIfNull(product.getStockNumber(), 0));
data.setIsSoldStock(data.getIsPauseSale());
data.setIsSale(data.getIsGrounding());
data.setIsStock(product.getIsStock());
return data;
}
return null;
}
@Override
public Map<Long, Integer> findShopProductStock(Long shopId) {
List<Product> list = productMapper.selectListByQuery(query().select(Product::getId, Product::getStockNumber).eq(Product::getShopId, shopId));
if (CollUtil.isEmpty(list)) {
return null;
}
return list.stream().collect(Collectors.toMap(Product::getId, Product::getStockNumber));
}
@Override
public void refreshProductStock(Long shopId, List<ShopProductVo> productList) {
Map<Long, Integer> stock = findShopProductStock(shopId);
if (MapUtil.isEmpty(stock)) {
return;
}
productList.parallelStream().forEach(record -> {
record.setStockNumber(stock.getOrDefault(record.getId(), 0));
refreshRedisStock(record.getShopId(), record.getId(), record.getStockNumber());
});
}
@Override
public void refreshProductStock(Map<Long, Integer> productStock, List<ShopProductVo> productList) {
if (MapUtil.isEmpty(productStock)) {
return;
}
productList.parallelStream().forEach(record -> {
record.setStockNumber(productStock.getOrDefault(record.getId(), 0));
if (record.getIsStock() == SystemConstants.OneZero.ONE) {
refreshRedisStock(record.getShopId(), record.getId(), record.getStockNumber());
} else {
redisService.del(StrUtil.format(CacheConstant.SHOP_PRODUCT_STOCK, record.getShopId(), record.getId()));
}
});
}
private void refreshRedisStock(Long shopId, Long productId, Integer stockNumber) {
String key = StrUtil.format(CacheConstant.SHOP_PRODUCT_STOCK, shopId, productId);
redisService.set(key, stockNumber);
}
/**
* 计算是否在可售时间内

View File

@@ -17,7 +17,6 @@
t1.unit_id,
t1.weight,
t1.end_time,
t1.is_stock,
t1.pack_fee,
t1.cover_img,
t1.warn_line,
@@ -29,7 +28,6 @@
t1.short_title,
t1.update_time,
t1.is_sold_stock,
t1.stock_number,
t1.is_refund_stock,
t1.select_spec_info,
t1.group_category_id,
@@ -82,7 +80,6 @@
t3.name as unit_name,
t1.is_sold_stock,
t1.sync_id as syncId,
t1.stock_number,
t1.type,
t1.group_type,
t1.days,
@@ -95,7 +92,6 @@
t1.pack_fee,
ifnull(t4.sales_volume, 0) as sales_volume,
t1.shop_id,
t1.is_stock,
t1.related_recommend
from tb_product t1
left join (select x.product_id,
@@ -271,16 +267,4 @@
</if>
GROUP BY a.id
</select>
<update id="updateProductStockNum">
update tb_product
<if test="type == 'add'">
set stock_number = stock_number + #{num}
</if>
<if test="type == 'sub'">
set stock_number = stock_number - #{num}
</if>
where id = #{id}
and is_stock = 1
and shop_id = #{shopId}
</update>
</mapper>