feat(product): 添加供应商信息并优化商品导入功能

- 在 GetProductBo 和 QueryProductBo 中添加供应商 ID 和名称字段
- 在 Product 实体中添加供应商 ID 字段
- 更新商品导入功能,支持导入供应商编号并进行供应商存在性校验
- 在创建商品时,普通商品类型必须选择供应商- 优化商品查询接口,支持按供应商 ID 查询
This commit is contained in:
lijiaqi 2024-11-21 09:12:38 +08:00
parent 1fe802ca6f
commit 3870e1a483
9 changed files with 104 additions and 17 deletions

View File

@ -2,20 +2,16 @@ package com.lframework.xingyun.basedata.bo.product.info;
import com.lframework.starter.common.constants.StringPool; import com.lframework.starter.common.constants.StringPool;
import com.lframework.starter.common.utils.CollectionUtil; import com.lframework.starter.common.utils.CollectionUtil;
import com.lframework.starter.common.utils.ObjectUtil;
import com.lframework.starter.web.annotations.convert.EnumConvert; import com.lframework.starter.web.annotations.convert.EnumConvert;
import com.lframework.starter.web.bo.BaseBo; import com.lframework.starter.web.bo.BaseBo;
import com.lframework.starter.web.common.utils.ApplicationUtil; import com.lframework.starter.web.common.utils.ApplicationUtil;
import com.lframework.xingyun.basedata.dto.product.ProductPropertyRelationDto; import com.lframework.xingyun.basedata.dto.product.ProductPropertyRelationDto;
import com.lframework.xingyun.basedata.entity.Product; import com.lframework.xingyun.basedata.entity.*;
import com.lframework.xingyun.basedata.entity.ProductBrand;
import com.lframework.xingyun.basedata.entity.ProductBundle;
import com.lframework.xingyun.basedata.entity.ProductCategory;
import com.lframework.xingyun.basedata.entity.ProductPurchase;
import com.lframework.xingyun.basedata.entity.ProductRetail;
import com.lframework.xingyun.basedata.entity.ProductSale;
import com.lframework.xingyun.basedata.enums.ColumnType; import com.lframework.xingyun.basedata.enums.ColumnType;
import com.lframework.xingyun.basedata.enums.ProductType; import com.lframework.xingyun.basedata.enums.ProductType;
import com.lframework.xingyun.basedata.service.product.*; import com.lframework.xingyun.basedata.service.product.*;
import com.lframework.xingyun.basedata.service.supplier.SupplierService;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
@ -171,6 +167,18 @@ public class GetProductBo extends BaseBo<Product> {
@ApiModelProperty("库存") @ApiModelProperty("库存")
private BigDecimal stock; private BigDecimal stock;
/**
* 供应商ID
*/
@ApiModelProperty("供应商ID")
private String supplierId;
/**
* 供应商名称
*/
@ApiModelProperty("供应商名称")
private String supplierName;
public GetProductBo() { public GetProductBo() {
} }
@ -244,6 +252,9 @@ public class GetProductBo extends BaseBo<Product> {
} }
ProductService productService = ApplicationUtil.getBean(ProductService.class); ProductService productService = ApplicationUtil.getBean(ProductService.class);
this.stock = productService.getStock(dto.getId()); this.stock = productService.getStock(dto.getId());
SupplierService supplierService = ApplicationUtil.getBean(SupplierService.class);
Supplier supplier = supplierService.findById(dto.getSupplierId());
this.supplierName = ObjectUtil.isNotNull(supplier) ? supplier.getName() : "";
} }
@Data @Data

View File

@ -1,19 +1,17 @@
package com.lframework.xingyun.basedata.bo.product.info; package com.lframework.xingyun.basedata.bo.product.info;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.lframework.starter.common.constants.StringPool; import com.lframework.starter.common.constants.StringPool;
import com.lframework.starter.common.utils.ObjectUtil;
import com.lframework.starter.web.annotations.convert.EnumConvert; import com.lframework.starter.web.annotations.convert.EnumConvert;
import com.lframework.starter.web.bo.BaseBo; import com.lframework.starter.web.bo.BaseBo;
import com.lframework.starter.web.common.utils.ApplicationUtil; import com.lframework.starter.web.common.utils.ApplicationUtil;
import com.lframework.xingyun.basedata.entity.Product; import com.lframework.xingyun.basedata.entity.*;
import com.lframework.xingyun.basedata.entity.ProductBrand;
import com.lframework.xingyun.basedata.entity.ProductCategory;
import com.lframework.xingyun.basedata.entity.ProductSale;
import com.lframework.xingyun.basedata.service.product.ProductBrandService; import com.lframework.xingyun.basedata.service.product.ProductBrandService;
import com.lframework.xingyun.basedata.service.product.ProductCategoryService; import com.lframework.xingyun.basedata.service.product.ProductCategoryService;
import com.lframework.xingyun.basedata.service.product.ProductSaleService; import com.lframework.xingyun.basedata.service.product.ProductSaleService;
import com.lframework.xingyun.basedata.service.product.ProductService; import com.lframework.xingyun.basedata.service.product.ProductService;
import com.lframework.xingyun.basedata.service.supplier.SupplierService;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -105,6 +103,18 @@ public class QueryProductBo extends BaseBo<Product> {
@ApiModelProperty("库存") @ApiModelProperty("库存")
private BigDecimal stock; private BigDecimal stock;
/**
* 供应商ID
*/
@ApiModelProperty("供应商ID")
private String supplierId;
/**
* 供应商名称
*/
@ApiModelProperty("供应商名称")
private String supplierName;
public QueryProductBo() { public QueryProductBo() {
} }
@ -131,5 +141,9 @@ public class QueryProductBo extends BaseBo<Product> {
ProductService productService = ApplicationUtil.getBean(ProductService.class); ProductService productService = ApplicationUtil.getBean(ProductService.class);
this.stock = productService.getStock(dto.getId()); this.stock = productService.getStock(dto.getId());
SupplierService supplierService = ApplicationUtil.getBean(SupplierService.class);
Supplier supplier = supplierService.findById(dto.getSupplierId());
this.supplierName = ObjectUtil.isNotNull(supplier) ? supplier.getName() : "";
} }
} }

View File

@ -8,6 +8,8 @@ import com.lframework.starter.web.dto.BaseDto;
import com.lframework.xingyun.basedata.enums.ProductType; import com.lframework.xingyun.basedata.enums.ProductType;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
/** /**
@ -141,4 +143,9 @@ public class Product extends BaseEntity implements BaseDto {
*/ */
@TableField(fill = FieldFill.INSERT_UPDATE) @TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime; private LocalDateTime updateTime;
/**
* 供应商ID
*/
private String supplierId;
} }

View File

@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lframework.starter.common.constants.PatternPool; import com.lframework.starter.common.constants.PatternPool;
import com.lframework.starter.common.exceptions.impl.DefaultClientException; import com.lframework.starter.common.exceptions.impl.DefaultClientException;
import com.lframework.starter.common.utils.NumberUtil; import com.lframework.starter.common.utils.NumberUtil;
import com.lframework.starter.common.utils.ObjectUtil;
import com.lframework.starter.common.utils.RegUtil; import com.lframework.starter.common.utils.RegUtil;
import com.lframework.starter.common.utils.StringUtil; import com.lframework.starter.common.utils.StringUtil;
import com.lframework.starter.web.common.utils.ApplicationUtil; import com.lframework.starter.web.common.utils.ApplicationUtil;
@ -15,6 +16,7 @@ import com.lframework.starter.web.utils.IdUtil;
import com.lframework.xingyun.basedata.entity.Product; import com.lframework.xingyun.basedata.entity.Product;
import com.lframework.xingyun.basedata.entity.ProductBrand; import com.lframework.xingyun.basedata.entity.ProductBrand;
import com.lframework.xingyun.basedata.entity.ProductCategory; import com.lframework.xingyun.basedata.entity.ProductCategory;
import com.lframework.xingyun.basedata.entity.Supplier;
import com.lframework.xingyun.basedata.enums.ProductType; import com.lframework.xingyun.basedata.enums.ProductType;
import com.lframework.xingyun.basedata.service.product.ProductBrandService; import com.lframework.xingyun.basedata.service.product.ProductBrandService;
import com.lframework.xingyun.basedata.service.product.ProductCategoryService; import com.lframework.xingyun.basedata.service.product.ProductCategoryService;
@ -22,6 +24,7 @@ import com.lframework.xingyun.basedata.service.product.ProductPurchaseService;
import com.lframework.xingyun.basedata.service.product.ProductRetailService; import com.lframework.xingyun.basedata.service.product.ProductRetailService;
import com.lframework.xingyun.basedata.service.product.ProductSaleService; import com.lframework.xingyun.basedata.service.product.ProductSaleService;
import com.lframework.xingyun.basedata.service.product.ProductService; import com.lframework.xingyun.basedata.service.product.ProductService;
import com.lframework.xingyun.basedata.service.supplier.SupplierService;
import com.lframework.xingyun.basedata.vo.product.purchase.CreateProductPurchaseVo; import com.lframework.xingyun.basedata.vo.product.purchase.CreateProductPurchaseVo;
import com.lframework.xingyun.basedata.vo.product.retail.CreateProductRetailVo; import com.lframework.xingyun.basedata.vo.product.retail.CreateProductRetailVo;
import com.lframework.xingyun.basedata.vo.product.sale.CreateProductSaleVo; import com.lframework.xingyun.basedata.vo.product.sale.CreateProductSaleVo;
@ -190,12 +193,16 @@ public class ProductImportListener extends ExcelImportListener<ProductImportMode
throw new DefaultClientException( throw new DefaultClientException(
"" + context.readRowHolder().getRowIndex() + "行“零售价”不允许小于0"); "" + context.readRowHolder().getRowIndex() + "行“零售价”不允许小于0");
} }
if(StringUtil.isBlank(data.getCode())){
throw new DefaultClientException( "" + context.readRowHolder().getRowIndex() + "行“供应商编号”不能为空");
}
} }
@Override @Override
protected void afterAllAnalysed(AnalysisContext context) { protected void afterAllAnalysed(AnalysisContext context) {
ProductService productService = ApplicationUtil.getBean(ProductService.class); ProductService productService = ApplicationUtil.getBean(ProductService.class);
SupplierService supplierService = ApplicationUtil.getBean(SupplierService.class);
List<ProductImportModel> datas = this.getDatas(); List<ProductImportModel> datas = this.getDatas();
for (int i = 0; i < datas.size(); i++) { for (int i = 0; i < datas.size(); i++) {
@ -206,11 +213,17 @@ public class ProductImportListener extends ExcelImportListener<ProductImportMode
if (productService.count(checkSkuCodeWrapper) > 0) { if (productService.count(checkSkuCodeWrapper) > 0) {
throw new DefaultClientException("" + (i + 1) + "行“商品SKU编号”重复请重新输入"); throw new DefaultClientException("" + (i + 1) + "行“商品SKU编号”重复请重新输入");
} }
Wrapper<Supplier> checkSupplierWrapper = Wrappers.lambdaQuery(Supplier.class)
.eq(Supplier::getCode, data.getSupplierCode());
Supplier checkSupplier = supplierService.getOne(checkSupplierWrapper);
if(ObjectUtil.isNull(checkSupplier)){
throw new DefaultClientException("" + (i + 1) + "行“供应商编号”不存在,请检查");
}
Product record = new Product(); Product record = new Product();
record.setId(IdUtil.getId()); record.setId(IdUtil.getId());
record.setSupplierId(checkSupplier.getId());
record.setCode(data.getCode()); record.setCode(data.getCode());
record.setName(data.getName()); record.setName(data.getName());
if (StringUtil.isNotBlank(data.getShortName())) { if (StringUtil.isNotBlank(data.getShortName())) {

View File

@ -5,6 +5,8 @@ import com.alibaba.excel.annotation.ExcelProperty;
import com.lframework.starter.web.annotations.excel.ExcelRequired; import com.lframework.starter.web.annotations.excel.ExcelRequired;
import com.lframework.starter.web.components.excel.ExcelModel; import com.lframework.starter.web.components.excel.ExcelModel;
import java.math.BigDecimal; import java.math.BigDecimal;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@Data @Data
@ -36,6 +38,13 @@ public class ProductImportModel implements ExcelModel {
@ExcelProperty("简称") @ExcelProperty("简称")
private String shortName; private String shortName;
/**
* 供应商编号
*/
@ExcelRequired
@ExcelProperty("供应商编号")
private String supplierCode;
/** /**
* SKU编号 * SKU编号
*/ */

View File

@ -18,10 +18,7 @@ import com.lframework.starter.web.utils.IdUtil;
import com.lframework.starter.web.utils.JsonUtil; import com.lframework.starter.web.utils.JsonUtil;
import com.lframework.starter.web.utils.PageHelperUtil; import com.lframework.starter.web.utils.PageHelperUtil;
import com.lframework.starter.web.utils.PageResultUtil; import com.lframework.starter.web.utils.PageResultUtil;
import com.lframework.xingyun.basedata.entity.Product; import com.lframework.xingyun.basedata.entity.*;
import com.lframework.xingyun.basedata.entity.ProductBundle;
import com.lframework.xingyun.basedata.entity.ProductProperty;
import com.lframework.xingyun.basedata.entity.ProductPropertyItem;
import com.lframework.xingyun.basedata.enums.ColumnType; import com.lframework.xingyun.basedata.enums.ColumnType;
import com.lframework.xingyun.basedata.enums.ProductCategoryNodeType; import com.lframework.xingyun.basedata.enums.ProductCategoryNodeType;
import com.lframework.xingyun.basedata.enums.ProductType; import com.lframework.xingyun.basedata.enums.ProductType;
@ -34,6 +31,7 @@ import com.lframework.xingyun.basedata.service.product.ProductPurchaseService;
import com.lframework.xingyun.basedata.service.product.ProductRetailService; import com.lframework.xingyun.basedata.service.product.ProductRetailService;
import com.lframework.xingyun.basedata.service.product.ProductSaleService; import com.lframework.xingyun.basedata.service.product.ProductSaleService;
import com.lframework.xingyun.basedata.service.product.ProductService; import com.lframework.xingyun.basedata.service.product.ProductService;
import com.lframework.xingyun.basedata.service.supplier.SupplierService;
import com.lframework.xingyun.basedata.vo.product.info.CreateProductVo; import com.lframework.xingyun.basedata.vo.product.info.CreateProductVo;
import com.lframework.xingyun.basedata.vo.product.info.ProductPropertyRelationVo; import com.lframework.xingyun.basedata.vo.product.info.ProductPropertyRelationVo;
import com.lframework.xingyun.basedata.vo.product.info.QueryProductSelectorVo; import com.lframework.xingyun.basedata.vo.product.info.QueryProductSelectorVo;
@ -90,6 +88,9 @@ public class ProductServiceImpl extends BaseMpServiceImpl<ProductMapper, Product
@Autowired @Autowired
private ProductBundleService productBundleService; private ProductBundleService productBundleService;
@Autowired
private SupplierService supplierService;
@Override @Override
public PageResult<Product> query(Integer pageIndex, Integer pageSize, QueryProductVo vo) { public PageResult<Product> query(Integer pageIndex, Integer pageSize, QueryProductVo vo) {
@ -214,16 +215,33 @@ public class ProductServiceImpl extends BaseMpServiceImpl<ProductMapper, Product
data.setUnit(vo.getUnit()); data.setUnit(vo.getUnit());
} }
data.setProductType(EnumUtil.getByCode(ProductType.class, vo.getProductType())); data.setProductType(EnumUtil.getByCode(ProductType.class, vo.getProductType()));
// 普通商品
if (data.getProductType() == ProductType.NORMAL){
if (StringUtil.isBlank(vo.getSupplierId())){
throw new DefaultClientException("请选择供应商!");
}
Supplier supplier = supplierService.findById(vo.getSupplierId());
if (ObjectUtil.isNull(supplier)){
throw new DefaultClientException("供应商不存在!");
}
}
data.setTaxRate(vo.getTaxRate()); data.setTaxRate(vo.getTaxRate());
data.setSaleTaxRate(vo.getSaleTaxRate()); data.setSaleTaxRate(vo.getSaleTaxRate());
data.setWeight(vo.getWeight()); data.setWeight(vo.getWeight());
data.setVolume(vo.getVolume()); data.setVolume(vo.getVolume());
data.setSupplierId(vo.getSupplierId());
data.setAvailable(Boolean.TRUE); data.setAvailable(Boolean.TRUE);
getBaseMapper().insert(data); getBaseMapper().insert(data);
// 组合商品 // 组合商品
if (data.getProductType() == ProductType.BUNDLE) { if (data.getProductType() == ProductType.BUNDLE) {
if (CollectionUtil.isEmpty(vo.getProductBundles())) { if (CollectionUtil.isEmpty(vo.getProductBundles())) {

View File

@ -150,5 +150,11 @@ public class CreateProductVo implements BaseVo, Serializable {
@ApiModelProperty("零售价") @ApiModelProperty("零售价")
private BigDecimal retailPrice; private BigDecimal retailPrice;
/**
* 供应商ID
*/
@ApiModelProperty("供应商ID")
private String supplierId;
} }

View File

@ -74,4 +74,10 @@ public class QueryProductVo extends SortPageVo implements BaseVo, Serializable {
*/ */
@ApiModelProperty("状态") @ApiModelProperty("状态")
private Boolean available; private Boolean available;
/**
* 供应商ID
*/
@ApiModelProperty("供应商ID")
private String supplierId;
} }

View File

@ -47,6 +47,9 @@
AND g.create_time <= #{vo.endTime} AND g.create_time <= #{vo.endTime}
]]> ]]>
</if> </if>
<if test="vo.supplierId != null and vo.supplierId != ''">
AND g.supplier_id = #{vo.supplierId}
</if>
</if> </if>
</where> </where>
ORDER BY g.code ORDER BY g.code