商品模块代码提交

This commit is contained in:
Tankaikai 2025-02-24 14:07:42 +08:00
parent e09b55938f
commit 2d8f120303
15 changed files with 901 additions and 3 deletions

View File

@ -0,0 +1,80 @@
package com.czg.controller.admin;
import com.czg.log.annotation.OperationLog;
import com.czg.product.param.ConsCheckStockParam;
import com.czg.product.param.ConsInOutStockHeadParam;
import com.czg.product.service.ConsStockFlowService;
import com.czg.product.vo.ConsCheckStockRecordVo;
import com.czg.resp.CzgResult;
import com.czg.utils.AssertUtil;
import com.czg.validator.ValidatorUtil;
import com.czg.validator.group.DefaultGroup;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 耗材进销存
*
* @author Tankaikai tankaikai@aliyun.com
* @since 1.0 2025-02-21
*/
@AllArgsConstructor
@RestController
@RequestMapping("/admin/product/stock")
public class ConsStockFlowController {
private final ConsStockFlowService consStockFlowService;
/**
* 耗材入库
*/
@PostMapping("in")
@OperationLog("耗材入库")
//@SaAdminCheckPermission("consStockFlow:in")
public CzgResult<Void> inStock(@RequestBody ConsInOutStockHeadParam param) {
ValidatorUtil.validateEntity(param, DefaultGroup.class);
ValidatorUtil.validateEntity(param.getBodyList(), DefaultGroup.class);
consStockFlowService.inStock(param);
return CzgResult.success();
}
/**
* 耗材出库
*/
@PostMapping("out")
@OperationLog("耗材出库")
//@SaAdminCheckPermission("consStockFlow:out")
public CzgResult<Void> outStock(@RequestBody ConsInOutStockHeadParam param) {
ValidatorUtil.validateEntity(param, DefaultGroup.class);
ValidatorUtil.validateEntity(param.getBodyList(), DefaultGroup.class);
consStockFlowService.outStock(param);
return CzgResult.success();
}
/**
* 库存盘点记录
* param conId 耗材ID
*/
@GetMapping("check-record")
@OperationLog("库存盘点记录")
//@SaAdminCheckPermission("consStockFlow:check-record")
public CzgResult<List<ConsCheckStockRecordVo>> checkStock(@RequestParam Long conId) {
AssertUtil.isNull(conId, "耗材ID不能为空");
List<ConsCheckStockRecordVo> data = consStockFlowService.getCheckStockRecordList(conId);
return CzgResult.success(data);
}
/**
* 库存盘点
*/
@PostMapping("check")
@OperationLog("库存盘点")
//@SaAdminCheckPermission("consStockFlow:check")
public CzgResult<Void> checkStock(@RequestBody ConsCheckStockParam param) {
ValidatorUtil.validateEntity(param, DefaultGroup.class);
consStockFlowService.checkStock(param);
return CzgResult.success();
}
}

View File

@ -0,0 +1,126 @@
package com.czg.product.dto;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 耗材库存变动记录
*
* @author Tankaikai tankaikai@aliyun.com
* @since 1.0 2025-02-21
*/
@Data
public class ConsStockFlowDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
private Long id;
/**
* 店铺id
*/
private Long shopId;
/**
* 供应商id
*/
private Long vendorId;
/**
* 出入库类型 in-入库 out-出库
*/
private String inOutType;
/**
* 出入库名目 manual-in:手动入库 manual-out:手动出库 win-in:盘盈入库 loss-out:盘亏出库 order-in:订单退款入库 order-out:订单消费出库
*/
private String inOutItem;
/**
* 出入库日期
*/
private LocalDate inOutDate;
/**
* 应付金额
*/
private BigDecimal amountPayable;
/**
* 实付金额
*/
private BigDecimal actualPaymentAmount;
/**
* 付款日期
*/
private LocalDate paymentDate;
/**
* 批次号
*/
private String batchNo;
/**
* 耗材名称
*/
private String conName;
/**
* 采购价/进价
*/
private BigDecimal purchasePrice;
/**
* 耗材id
*/
private Long conId;
/**
* 单位
*/
private String unitName;
/**
* 变动前的库存
*/
private BigDecimal beforeNumber;
/**
* 出入库数量
*/
private BigDecimal inOutNumber;
/**
* 变动后的库存
*/
private BigDecimal afterNumber;
/**
* 小计
*/
private BigDecimal subTotal;
/**
* 商品id
*/
private Long productId;
/**
* sku id
*/
private Long skuId;
/**
* 商品订单id
*/
private Long orderId;
/**
* 创建人id
*/
private Long createUserId;
/**
* 创建人name
*/
private String createUserName;
/**
* 创建时间
*/
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
/**
* 备注
*/
private String remark;
}

View File

@ -0,0 +1,130 @@
package com.czg.product.entity;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 耗材库存变动记录
*
* @author Tankaikai tankaikai@aliyun.com
* @since 1.0 2025-02-21
*/
@Data
@Table("tb_cons_stock_flow")
public class ConsStockFlow implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
@Id(keyType = KeyType.Auto)
private Long id;
/**
* 店铺id
*/
private Long shopId;
/**
* 供应商id
*/
private Long vendorId;
/**
* 出入库类型 in-入库 out-出库
*/
private String inOutType;
/**
* 出入库名目 manual-in:手动入库 manual-out:手动出库 win-in:盘盈入库 loss-out:盘亏出库 order-in:订单退款入库 order-out:订单消费出库
*/
private String inOutItem;
/**
* 出入库日期
*/
private LocalDate inOutDate;
/**
* 应付金额
*/
private BigDecimal amountPayable;
/**
* 实付金额
*/
private BigDecimal actualPaymentAmount;
/**
* 付款日期
*/
private LocalDate paymentDate;
/**
* 批次号
*/
private String batchNo;
/**
* 耗材id
*/
private Long conId;
/**
* 耗材名称
*/
private String conName;
/**
* 采购价/进价
*/
private BigDecimal purchasePrice;
/**
* 单位
*/
private String unitName;
/**
* 变动前的库存
*/
private BigDecimal beforeNumber;
/**
* 出入库数量
*/
private BigDecimal inOutNumber;
/**
* 变动后的库存
*/
private BigDecimal afterNumber;
/**
* 小计
*/
private BigDecimal subTotal;
/**
* 商品id
*/
private Long productId;
/**
* sku id
*/
private Long skuId;
/**
* 商品订单id
*/
private Long orderId;
/**
* 创建人id
*/
private Long createUserId;
/**
* 创建人name
*/
private String createUserName;
/**
* 创建时间
*/
@Column(onInsertValue = "now()")
private LocalDateTime createTime;
/**
* 备注
*/
private String remark;
}

View File

@ -0,0 +1,50 @@
package com.czg.product.enums;
/**
* 出入库名目枚举
*
* @author tankaikai
* @since 2025-02-24 09:54
*/
public enum InOutItemEnum {
/**
* 手动入库
*/
MANUAL_IN("manual-in"),
/**
* 手动出库
*/
MANUAL_OUT("manual-out"),
/**
* 盘盈入库
*/
WIN_IN("win-in"),
/**
* 盘亏出库
*/
LOSS_OUT("loss-out"),
/**
* 订单退款入库
*/
ORDER_IN("order-in"),
/**
* 订单消费出库
*/
ORDER_OUT("order-out");
private String value;
InOutItemEnum(String value) {
this.value = value;
}
public String value() {
return this.value;
}
}

View File

@ -0,0 +1,30 @@
package com.czg.product.enums;
/**
* 出入库类型枚举
*
* @author tankaikai
* @since 2025-02-24 09:54
*/
public enum InOutTypeEnum {
/**
* 入库
*/
IN("in"),
/**
* 出库
*/
OUT("out");
private String value;
InOutTypeEnum(String value) {
this.value = value;
}
public String value() {
return this.value;
}
}

View File

@ -0,0 +1,58 @@
package com.czg.product.param;
import com.czg.validator.group.DefaultGroup;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 库存盘点入参
*
* @author Tankaikai tankaikai@aliyun.com
* @since 1.0 2025-02-20
*/
@Data
public class ConsCheckStockParam implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 耗材id
*/
@NotNull(message = "耗材id不能为空", groups = DefaultGroup.class)
private Long conId;
/**
* 耗材名称
*/
@NotBlank(message = "耗材名称不能为空", groups = DefaultGroup.class)
private String conName;
/**
* 账存数量
*/
@NotNull(message = "账存数量不能为空", groups = DefaultGroup.class)
private BigDecimal stockNumber;
/**
* 实际数量
*/
@NotNull(message = "实际数量不能为空", groups = DefaultGroup.class)
private BigDecimal actualNumber;
/**
* 盈亏数量
*/
@NotNull(message = "盈亏数量不能为空", groups = DefaultGroup.class)
private BigDecimal winLossNumber;
/**
* 单价
*/
@NotNull(message = "单价不能为空", groups = DefaultGroup.class)
private BigDecimal price;
/**
* 备注
*/
private String remark;
}

View File

@ -0,0 +1,56 @@
package com.czg.product.param;
import com.czg.validator.group.DefaultGroup;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 出入库耗材入参
*
* @author Tankaikai tankaikai@aliyun.com
* @since 1.0 2025-02-20
*/
@Data
public class ConsInOutStockBodyParam implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 耗材id
*/
@NotNull(message = "耗材id不能为空", groups = DefaultGroup.class)
private String conId;
/**
* 耗材名称
*/
@NotBlank(message = "耗材名称不能为空", groups = DefaultGroup.class)
private String conName;
/**
* 采购价/进价
*/
@NotNull(message = "进价不能为空", groups = DefaultGroup.class)
private BigDecimal purchasePrice;
/**
* 单位
*/
@NotBlank(message = "单位不能为空", groups = DefaultGroup.class)
private String unitName;
/**
* 出入库数量
*/
@NotNull(message = "数量不能为空", groups = DefaultGroup.class)
@Min(value = 0, message = "数量不能小于0")
private BigDecimal inOutNumber;
/**
* 小计
*/
@NotNull(message = "小计不能为空", groups = DefaultGroup.class)
private BigDecimal subTotal;
}

View File

@ -0,0 +1,60 @@
package com.czg.product.param;
import com.alibaba.fastjson2.annotation.JSONField;
import com.czg.validator.group.DefaultGroup;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
/**
* 出入库入参
*
* @author Tankaikai tankaikai@aliyun.com
* @since 1.0 2025-02-20
*/
@Data
public class ConsInOutStockHeadParam implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 供应商id
*/
private Long vendorId;
/**
* 出入库日期
*/
@NotNull(message = "出入库日期不能为空", groups = DefaultGroup.class)
@JSONField(format = "yyyy-MM-dd")
private LocalDate inOutDate;
/**
* 应付金额
*/
private BigDecimal amountPayable;
/**
* 实付金额
*/
private BigDecimal actualPaymentAmount;
/**
* 付款日期
*/
private LocalDate paymentDate;
/**
* 批次号
*/
private String batchNo;
/**
* 备注
*/
private String remark;
/**
* 耗材明细列表
*/
List<ConsInOutStockBodyParam> bodyList;
}

View File

@ -0,0 +1,49 @@
package com.czg.product.service;
import com.czg.product.entity.ConsStockFlow;
import com.czg.product.param.ConsCheckStockParam;
import com.czg.product.param.ConsInOutStockHeadParam;
import com.czg.product.vo.ConsCheckStockRecordVo;
import com.mybatisflex.core.service.IService;
import java.util.List;
/**
* 耗材库存变动记录
*
* @author Tankaikai tankaikai@aliyun.com
* @since 1.0 2025-02-21
*/
public interface ConsStockFlowService extends IService<ConsStockFlow> {
/**
* 手动入库
*
* @param param 手动出库入参
*/
void inStock(ConsInOutStockHeadParam param);
/**
* 手动出库
*
* @param param 手动出库入参
*/
void outStock(ConsInOutStockHeadParam param);
/**
* 库存盘点
*
* @param param 库存盘点入参
*/
void checkStock(ConsCheckStockParam param);
/**
* 获取盘点记录
*
* @param conId 耗材id
* @return 盘点记录列表
*/
List<ConsCheckStockRecordVo> getCheckStockRecordList(Long conId);
}

View File

@ -0,0 +1,73 @@
package com.czg.product.vo;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 库存盘点记录
*
* @author tankaikai
* @since 2025-02-24 13:40
*/
@Data
public class ConsCheckStockRecordVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 耗材id
*/
private Long conId;
/**
* 耗材名称
*/
private String conName;
/**
* 单价
*/
private BigDecimal purchasePrice;
/**
* 账存数量
*/
private BigDecimal beforeNumber;
/**
* 盈亏数量
*/
private BigDecimal inOutNumber;
/**
* 盘点后的数量
*/
@JSONField(serialize = false)
private BigDecimal afterNumber;
/**
* 盈亏金额
*/
private BigDecimal winLossAmount;
/**
* 实际库存
*/
private BigDecimal actualNumber;
/**
* 盘点时间
*/
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
/**
* 备注
*/
private String remark;
public BigDecimal getWinLossAmount() {
return NumberUtil.mul(purchasePrice, purchasePrice);
}
public BigDecimal getActualNumber() {
return afterNumber;
}
}

View File

@ -19,7 +19,7 @@ public class ShopProductSkuInfoVo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
* sku-id
*/
private Long id;
/**

View File

@ -0,0 +1,16 @@
package com.czg.service.product.mapper;
import com.czg.product.entity.ConsStockFlow;
import com.mybatisflex.core.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 耗材库存变动记录
*
* @author Tankaikai tankaikai@aliyun.com
* @since 1.0 2025-02-21
*/
@Mapper
public interface ConsStockFlowMapper extends BaseMapper<ConsStockFlow> {
}

View File

@ -0,0 +1,164 @@
package com.czg.service.product.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.czg.exception.CzgException;
import com.czg.product.dto.ConsStockFlowDTO;
import com.czg.product.entity.ConsInfo;
import com.czg.product.entity.ConsStockFlow;
import com.czg.product.enums.InOutItemEnum;
import com.czg.product.enums.InOutTypeEnum;
import com.czg.product.param.ConsCheckStockParam;
import com.czg.product.param.ConsInOutStockHeadParam;
import com.czg.product.service.ConsStockFlowService;
import com.czg.product.vo.ConsCheckStockRecordVo;
import com.czg.sa.StpKit;
import com.czg.service.product.mapper.ConsInfoMapper;
import com.czg.service.product.mapper.ConsStockFlowMapper;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* 耗材库存变动记录
*
* @author Tankaikai tankaikai@aliyun.com
* @since 1.0 2025-02-21
*/
@AllArgsConstructor
@Service
public class ConsStockFlowServiceImpl extends ServiceImpl<ConsStockFlowMapper, ConsStockFlow> implements ConsStockFlowService {
private final ConsInfoMapper consInfoMapper;
private QueryWrapper buildQueryWrapper(ConsStockFlowDTO param) {
QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
/*if (StrUtil.isNotEmpty(param.getName())) {
queryWrapper.like(ConsStockFlow::getName, param.getName());
}*/
Long shopId = StpKit.USER.getShopId(0L);
queryWrapper.eq(ConsStockFlow::getShopId, shopId);
queryWrapper.orderBy(ConsStockFlow::getId, false);
return queryWrapper;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void inStock(ConsInOutStockHeadParam param) {
Long shopId = StpKit.USER.getShopId(0L);
Long createUserId = StpKit.USER.getLoginIdAsLong();
String createUserName = StpKit.USER.getAccount();
ConsStockFlow head = BeanUtil.copyProperties(param, ConsStockFlow.class);
List<ConsStockFlow> entityList = BeanUtil.copyToList(param.getBodyList(), ConsStockFlow.class);
List<ConsStockFlow> insertList = new ArrayList<>();
List<ConsInfo> updateStockList = new ArrayList<>();
for (ConsStockFlow entity : entityList) {
BeanUtil.copyProperties(head, entity, CopyOptions.create().ignoreNullValue());
entity.setShopId(shopId);
entity.setInOutType(InOutTypeEnum.IN.value());
entity.setInOutItem(InOutItemEnum.MANUAL_IN.value());
entity.setCreateUserId(createUserId);
entity.setCreateUserName(createUserName);
Long conId = entity.getConId();
ConsInfo consInfo = consInfoMapper.selectOneById(conId);
if (consInfo == null) {
throw new CzgException(StrUtil.format("耗材{}不存在", entity.getConName()));
}
entity.setBeforeNumber(consInfo.getStockNumber());
entity.setAfterNumber(NumberUtil.add(entity.getBeforeNumber(), entity.getInOutNumber()));
insertList.add(entity);
consInfo.setStockNumber(entity.getAfterNumber());
updateStockList.add(consInfo);
}
super.saveBatch(insertList);
updateStockList.parallelStream().forEach(consInfoMapper::update);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void outStock(ConsInOutStockHeadParam param) {
Long shopId = StpKit.USER.getShopId(0L);
Long createUserId = StpKit.USER.getLoginIdAsLong();
String createUserName = StpKit.USER.getAccount();
ConsStockFlow head = BeanUtil.copyProperties(param, ConsStockFlow.class);
List<ConsStockFlow> entityList = BeanUtil.copyToList(param.getBodyList(), ConsStockFlow.class);
List<ConsStockFlow> insertList = new ArrayList<>();
List<ConsInfo> updateStockList = new ArrayList<>();
for (ConsStockFlow entity : entityList) {
BeanUtil.copyProperties(head, entity, CopyOptions.create().ignoreNullValue());
entity.setInOutNumber(NumberUtil.sub(BigDecimal.ZERO, entity.getInOutNumber()));
entity.setShopId(shopId);
entity.setInOutType(InOutTypeEnum.OUT.value());
entity.setInOutItem(InOutItemEnum.MANUAL_OUT.value());
entity.setCreateUserId(createUserId);
entity.setCreateUserName(createUserName);
Long conId = entity.getConId();
ConsInfo consInfo = consInfoMapper.selectOneById(conId);
if (consInfo == null) {
throw new CzgException(StrUtil.format("耗材{}不存在", entity.getConName()));
}
entity.setBeforeNumber(consInfo.getStockNumber());
entity.setAfterNumber(NumberUtil.add(entity.getBeforeNumber(), entity.getInOutNumber()));
insertList.add(entity);
consInfo.setStockNumber(entity.getAfterNumber());
updateStockList.add(consInfo);
}
super.saveBatch(insertList);
updateStockList.parallelStream().forEach(consInfoMapper::update);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void checkStock(ConsCheckStockParam param) {
Long shopId = StpKit.USER.getShopId(0L);
Long createUserId = StpKit.USER.getLoginIdAsLong();
String createUserName = StpKit.USER.getAccount();
ConsStockFlow entity = new ConsStockFlow();
entity.setCreateUserId(createUserId);
entity.setCreateUserName(createUserName);
entity.setShopId(shopId);
entity.setConId(param.getConId());
entity.setConName(param.getConName());
entity.setPurchasePrice(param.getPrice());
ConsInfo consInfo = consInfoMapper.selectOneById(param.getConId());
if (consInfo == null) {
throw new CzgException(StrUtil.format("耗材{}不存在", entity.getConName()));
}
BigDecimal winLossNumber = NumberUtil.sub(param.getActualNumber(), param.getStockNumber());
if (!NumberUtil.equals(winLossNumber, param.getWinLossNumber())) {
throw new CzgException(StrUtil.format("耗材{}存在发生变动,请刷新后重试", entity.getConName()));
}
entity.setBeforeNumber(consInfo.getStockNumber());
entity.setInOutNumber(winLossNumber);
entity.setAfterNumber(NumberUtil.add(entity.getBeforeNumber(), entity.getInOutNumber()));
if (NumberUtil.isLess(winLossNumber, BigDecimal.ZERO)) {
entity.setInOutType(InOutTypeEnum.OUT.value());
entity.setInOutItem(InOutItemEnum.LOSS_OUT.value());
} else {
entity.setInOutType(InOutTypeEnum.IN.value());
entity.setInOutItem(InOutItemEnum.WIN_IN.value());
}
entity.setSubTotal(NumberUtil.mul(winLossNumber, param.getPrice()));
entity.setRemark(param.getRemark());
super.save(entity);
consInfo.setStockNumber(entity.getAfterNumber());
consInfoMapper.update(consInfo);
}
@Override
public List<ConsCheckStockRecordVo> getCheckStockRecordList(Long conId) {
Long shopId = StpKit.USER.getShopId(0L);
return super.mapper.selectListByQueryAs(query().eq(ConsStockFlow::getShopId, shopId).eq(ConsStockFlow::getConId, conId).orderBy(ConsStockFlow::getId, true), ConsCheckStockRecordVo.class);
}
}

View File

@ -36,7 +36,7 @@ public class ProdConsRelationServiceImpl extends ServiceImpl<ProdConsRelationMap
private QueryWrapper buildQueryWrapper(ProdConsRelationDTO param) {
QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
Long shopId = StpKit.USER.getLoginIdAsLong();
Long shopId = StpKit.USER.getShopId(0L);
queryWrapper.eq(ProdConsRelation::getShopId, shopId);
queryWrapper.orderBy(ProdConsRelation::getId, false);
return queryWrapper;
@ -51,7 +51,7 @@ public class ProdConsRelationServiceImpl extends ServiceImpl<ProdConsRelationMap
@Override
@Transactional(rollbackFor = Exception.class)
public boolean saveProdConsRelation(ProdConsBindDTO dto) {
Long shopId = StpKit.USER.getLoginIdAsLong();
Long shopId = StpKit.USER.getShopId(0L);
long count = productMapper.selectCountByQuery(query().eq(Product::getShopId, shopId).eq(Product::getId, dto.getId()));
if (count == 0) {
throw new CzgException("商品不存在");

View File

@ -0,0 +1,6 @@
<?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.product.mapper.ConsStockFlowMapper">
</mapper>