|
|
@@ -1,13 +1,10 @@
|
|
|
package com.ylx.massage.service.impl;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.ylx.massage.domain.*;
|
|
|
-import com.ylx.massage.domain.dto.ProductCreateDTO;
|
|
|
-import com.ylx.massage.domain.dto.ProductSkuDTO;
|
|
|
-import com.ylx.massage.domain.dto.ProductSpecDTO;
|
|
|
-import com.ylx.massage.domain.dto.ProductSpecSetupDTO;
|
|
|
-import com.ylx.massage.domain.dto.ProductSpecValueDTO;
|
|
|
+import com.ylx.massage.domain.dto.*;
|
|
|
import com.ylx.massage.domain.vo.SpecComboVO;
|
|
|
import com.ylx.massage.mapper.*;
|
|
|
import com.ylx.massage.service.ProductService;
|
|
|
@@ -18,6 +15,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
+import java.math.BigDecimal;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.*;
|
|
|
@@ -61,10 +59,20 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|
|
throw new RuntimeException("商品分类不存在");
|
|
|
}
|
|
|
|
|
|
+ // 校验规格列表是否为空
|
|
|
+ if (CollectionUtils.isEmpty(dto.getSpecList())) {
|
|
|
+ throw new RuntimeException("商品规格不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验SKU列表是否为空
|
|
|
+ if (CollectionUtils.isEmpty(dto.getSkuList())) {
|
|
|
+ throw new RuntimeException("商品SKU不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
// 2. 保存商品基本信息
|
|
|
Product product = new Product();
|
|
|
- product.setProductNo(dto.getProductNo());
|
|
|
product.setCategoryId(dto.getCategoryId());
|
|
|
+ product.setProductNo(dto.getProductNo());
|
|
|
product.setName(dto.getName());
|
|
|
product.setProductMainImage(dto.getProductMainImage());
|
|
|
product.setProductImage(dto.getProductImage());
|
|
|
@@ -75,9 +83,44 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|
|
product.setServicePromise(dto.getServicePromise());
|
|
|
product.setSaleStartTime(dto.getSaleStartTime());
|
|
|
product.setSaleEndTime(dto.getSaleEndTime());
|
|
|
- //product.setHasSpec(dto.getHasSpec());
|
|
|
+ //判断付款方式
|
|
|
+ Integer paymentType = dto.getPaymentType();
|
|
|
+ List<ProductSkuDTO> skuList = dto.getSkuList();
|
|
|
+ switch (paymentType) {
|
|
|
+ // 积分支付
|
|
|
+ case 1:
|
|
|
+ Integer pricePoint = skuList.get(0).getPricePoint();
|
|
|
+ //积分价格不能为空
|
|
|
+ if (pricePoint == null) {
|
|
|
+ throw new RuntimeException("积分价格不能为空");
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ // 金额支付
|
|
|
+ case 2:
|
|
|
+ BigDecimal priceMoney = skuList.get(0).getPriceMoney();
|
|
|
+ //金额价格不能为空
|
|
|
+ if (priceMoney == null) {
|
|
|
+ throw new RuntimeException("金额价格不能为空");
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ // 积分+金额支付
|
|
|
+ case 3:
|
|
|
+ Integer pricePoint1 = skuList.get(0).getPricePoint();
|
|
|
+ BigDecimal priceMoney1 = skuList.get(0).getPriceMoney();
|
|
|
+ //积分价格不能为空
|
|
|
+ if (pricePoint1 == null) {
|
|
|
+ throw new RuntimeException("积分价格不能为空");
|
|
|
+ }
|
|
|
+ //金额价格不能为空
|
|
|
+ if (priceMoney1 == null) {
|
|
|
+ throw new RuntimeException("金额价格不能为空");
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new RuntimeException("付款方式错误");
|
|
|
+ }
|
|
|
// 设置付款方式
|
|
|
- product.setPaymentType(dto.getPaymentType());
|
|
|
+ product.setPaymentType(paymentType);
|
|
|
product.setStatus(0); // 默认下架
|
|
|
product.setSales(0); // 初始销量为0
|
|
|
product.setDeleted(0); // 未删除
|
|
|
@@ -91,15 +134,125 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|
|
this.save(product);
|
|
|
Long productId = product.getId();
|
|
|
|
|
|
- // 3. 如果有规格,保存规格和SKU
|
|
|
- if (!CollectionUtils.isEmpty(dto.getSpecList())) {
|
|
|
- saveProductSpecsAndSkus(productId, dto);
|
|
|
- }
|
|
|
-
|
|
|
+ // 3. 保存规格和SKU
|
|
|
+ saveProductSpecsAndSkus(productId, dto);
|
|
|
log.info("商品创建成功,商品ID:{},商品编号:{}", productId, dto.getProductNo());
|
|
|
return productId;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 修改商品
|
|
|
+ *
|
|
|
+ * @param dto 修改商品请求DTO
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void updateProduct(ProductUpdateDTO dto) {
|
|
|
+ // 1. 校验商品是否存在
|
|
|
+ Product product = this.getById(dto.getId());
|
|
|
+ if (product == null) {
|
|
|
+ throw new RuntimeException("商品不存在");
|
|
|
+ }
|
|
|
+ // 2. 校验分类是否存在
|
|
|
+ ProductCategory category = productCategoryMapper.selectById(dto.getCategoryId());
|
|
|
+ if (category == null) {
|
|
|
+ throw new RuntimeException("商品分类不存在");
|
|
|
+ }
|
|
|
+ // 3. 校验规格列表是否为空
|
|
|
+ if (CollectionUtils.isEmpty(dto.getSpecList())) {
|
|
|
+ throw new RuntimeException("商品规格不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 校验SKU列表是否为空
|
|
|
+ if (CollectionUtils.isEmpty(dto.getSkuList())) {
|
|
|
+ throw new RuntimeException("商品SKU不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ //更新商品的信息
|
|
|
+ product.setCategoryId(dto.getCategoryId());
|
|
|
+ product.setName(dto.getName());
|
|
|
+ product.setProductMainImage(dto.getProductMainImage());
|
|
|
+ product.setProductImage(dto.getProductImage());
|
|
|
+ product.setSummary(dto.getSummary());
|
|
|
+ product.setDetail(dto.getDetail());
|
|
|
+ product.setPaymentType(dto.getPaymentType());
|
|
|
+ product.setFreight(dto.getFreight());
|
|
|
+ product.setDeliveryTime(dto.getDeliveryTime());
|
|
|
+ product.setServicePromise(dto.getServicePromise());
|
|
|
+ product.setSaleStartTime(dto.getSaleStartTime());
|
|
|
+ product.setSaleEndTime(dto.getSaleEndTime());
|
|
|
+ this.updateById(product);
|
|
|
+ //更新规格
|
|
|
+ updateProductSpecs(product.getId(), dto.getSpecList());
|
|
|
+ //更新SKU
|
|
|
+ updateProductSkus(product.getId(), dto.getSkuList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新商品规格
|
|
|
+ *
|
|
|
+ * @param productId 商品ID
|
|
|
+ * @param specList 商品规格列表
|
|
|
+ */
|
|
|
+ public void updateProductSpecs(Long productId, List<ProductSpecDTO> specList) {
|
|
|
+ //删除商品规格
|
|
|
+ productSpecMapper.delete(new LambdaQueryWrapper<ProductSpec>().eq(ProductSpec::getProductId, productId));
|
|
|
+ //删除商品规格值
|
|
|
+ productSpecValueMapper.delete(new LambdaQueryWrapper<ProductSpecValue>().eq(ProductSpecValue::getProductId, productId));
|
|
|
+ //添加商品规格
|
|
|
+ for (ProductSpecDTO spec : specList) {
|
|
|
+ ProductSpec productSpec = new ProductSpec();
|
|
|
+ productSpec.setProductId(productId);
|
|
|
+ productSpec.setSpecName(spec.getSpecName());
|
|
|
+ productSpec.setSort(spec.getSort());
|
|
|
+ productSpecMapper.insert(productSpec);
|
|
|
+ //添加商品规格值
|
|
|
+ for (ProductSpecValueDTO value : spec.getSpecValues()) {
|
|
|
+ ProductSpecValue productSpecValue = new ProductSpecValue();
|
|
|
+ productSpecValue.setSpecId(productSpec.getId());
|
|
|
+ productSpecValue.setProductId(productId);
|
|
|
+ productSpecValue.setSpecValue(value.getSpecValue());
|
|
|
+ productSpecValue.setSort(value.getSort());
|
|
|
+ productSpecValueMapper.insert(productSpecValue);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /*for (ProductSpecDTO spec : specList) {
|
|
|
+ ProductSpec productSpec = new ProductSpec();
|
|
|
+ productSpec.setSpecName(spec.getSpecName());
|
|
|
+ productSpec.setSort(spec.getSort());
|
|
|
+ productSpecMapper.update(productSpec, new LambdaUpdateWrapper<ProductSpec>().eq(ProductSpec::getProductId, productId));
|
|
|
+
|
|
|
+ // 更新商品规格值
|
|
|
+ for (ProductSpecValueDTO value : spec.getSpecValues()) {
|
|
|
+ ProductSpecValue productSpecValue = new ProductSpecValue();
|
|
|
+ productSpecValue.setSpecValue(value.getSpecValue());
|
|
|
+ productSpecValue.setSort(value.getSort());
|
|
|
+ productSpecValueMapper.update(productSpecValue, new LambdaUpdateWrapper<ProductSpecValue>().eq(ProductSpecValue::getProductId, productId));
|
|
|
+ }
|
|
|
+ }*/
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新商品SKU
|
|
|
+ */
|
|
|
+ public void updateProductSkus(Long productId, List<ProductSkuDTO> skuList) {
|
|
|
+ //删除商品SKU
|
|
|
+ productSkuMapper.delete(new LambdaQueryWrapper<ProductSku>().eq(ProductSku::getProductId, productId));
|
|
|
+ //添加商品SKU
|
|
|
+ for (ProductSkuDTO sku : skuList) {
|
|
|
+ ProductSku productSku = new ProductSku();
|
|
|
+ productSku.setProductId(productId);
|
|
|
+ productSku.setSkuNo(generateSkuNo(productId));
|
|
|
+ productSku.setSpecCombo(sku.getSpecCombo());
|
|
|
+ productSku.setImage(sku.getImage());
|
|
|
+ productSku.setPriceMoney(sku.getPriceMoney());
|
|
|
+ productSku.setPricePoint(sku.getPricePoint());
|
|
|
+ productSku.setOriginPrice(sku.getOriginPrice());
|
|
|
+ productSku.setStock(sku.getStock());
|
|
|
+ productSkuMapper.insert(productSku);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 生成商品编号
|
|
|
* 规则:分类编码 + 当前日期(yyyyMMdd) + 序列号(3位)
|
|
|
@@ -172,7 +325,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|
|
* 保存商品规格和SKU
|
|
|
*
|
|
|
* @param productId 商品ID
|
|
|
- * @param dto 商品创建DTO
|
|
|
+ * @param dto 商品创建DTO
|
|
|
*/
|
|
|
private void saveProductSpecsAndSkus(Long productId, ProductCreateDTO dto) {
|
|
|
List<ProductSpecDTO> specList = dto.getSpecList();
|
|
|
@@ -182,15 +335,17 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|
|
throw new RuntimeException("商品必须包含规格和SKU信息");
|
|
|
}
|
|
|
|
|
|
- // 保存规格名和规格值,并记录ID映射
|
|
|
+ // 保存规格名和规格值
|
|
|
AtomicInteger specIndex = new AtomicInteger(0);
|
|
|
|
|
|
for (ProductSpecDTO specDTO : specList) {
|
|
|
// 保存规格名
|
|
|
ProductSpec spec = new ProductSpec();
|
|
|
spec.setProductId(productId);
|
|
|
+ spec.setProductNo(dto.getProductNo());
|
|
|
spec.setSpecName(specDTO.getSpecName());
|
|
|
spec.setSort(specDTO.getSort() != null ? specDTO.getSort() : specIndex.get() + 1);
|
|
|
+ // 插入product_spec表
|
|
|
productSpecMapper.insert(spec);
|
|
|
Long specId = spec.getId();
|
|
|
|
|
|
@@ -201,9 +356,10 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|
|
ProductSpecValue specValue = new ProductSpecValue();
|
|
|
specValue.setSpecId(specId);
|
|
|
specValue.setProductId(productId);
|
|
|
+ specValue.setProductNo(dto.getProductNo());
|
|
|
specValue.setSpecValue(valueDTO.getSpecValue());
|
|
|
specValue.setSort(valueDTO.getSort() != null ? valueDTO.getSort() : valueIndex.get() + 1);
|
|
|
- specValue.setCreateTime(LocalDateTime.now());
|
|
|
+ // 插入product_spec_value表
|
|
|
productSpecValueMapper.insert(specValue);
|
|
|
valueIndex.getAndIncrement();
|
|
|
}
|
|
|
@@ -218,7 +374,6 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|
|
sku.setSkuNo(generateSkuNo(productId));
|
|
|
sku.setSpecCombo(skuDTO.getSpecCombo());
|
|
|
sku.setImage(skuDTO.getImage());
|
|
|
- //sku.setSpecValueIds(skuDTO.getSpecValueIndexCombo());
|
|
|
sku.setPriceMoney(skuDTO.getPriceMoney());
|
|
|
sku.setPricePoint(skuDTO.getPricePoint());
|
|
|
sku.setOriginPrice(skuDTO.getOriginPrice());
|
|
|
@@ -231,6 +386,9 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|
|
|
|
|
/**
|
|
|
* 生成SKU编号
|
|
|
+ *
|
|
|
+ * @param productId 商品ID
|
|
|
+ * @return 生成的SKU编号
|
|
|
*/
|
|
|
private String generateSkuNo(Long productId) {
|
|
|
return "SKU" + productId + System.currentTimeMillis();
|
|
|
@@ -239,7 +397,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|
|
/**
|
|
|
* 新增商品规格
|
|
|
*
|
|
|
- @param dto 规格设置请求DTO
|
|
|
+ * @param dto 规格设置请求DTO
|
|
|
*/
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
@@ -285,7 +443,8 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取商品规格组合(笛卡尔积)
|
|
|
+ * 获取商品规格组合
|
|
|
+ *
|
|
|
* @param productId 商品ID
|
|
|
* @return List<SpecComboVO> 规格组合列表
|
|
|
*/
|
|
|
@@ -300,6 +459,9 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|
|
return Collections.emptyList();
|
|
|
}
|
|
|
|
|
|
+ // 获取商品ID
|
|
|
+ Long productId = specList.get(0).getProductId();
|
|
|
+
|
|
|
// 查询所有规格值
|
|
|
LambdaQueryWrapper<ProductSpecValue> valueWrapper = new LambdaQueryWrapper<>();
|
|
|
valueWrapper.eq(ProductSpecValue::getProductNo, productNo).orderByAsc(ProductSpecValue::getSort);
|
|
|
@@ -335,23 +497,24 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|
|
for (List<SpecComboVO.SpecNameValue> combo : cartesianProduct) {
|
|
|
SpecComboVO vo = new SpecComboVO();
|
|
|
vo.setIndex(index++);
|
|
|
-
|
|
|
List<String> specValues = combo.stream().map(SpecComboVO.SpecNameValue::getSpecValue).collect(Collectors.toList());
|
|
|
vo.setSpecValues(specValues);
|
|
|
|
|
|
- /*List<Long> specValueIds = combo.stream().map(SpecComboVO.SpecNameValue::getSpecValueId).collect(Collectors.toList());
|
|
|
- vo.setSpecValueIds(specValueIds);*/
|
|
|
String join = String.join(",", specValues);
|
|
|
log.info("规格值文本:{}", join);
|
|
|
vo.setSpecValueText(join);
|
|
|
//根据规格值查询规格的图片
|
|
|
LambdaQueryWrapper<ProductSku> eq = new LambdaQueryWrapper<ProductSku>().eq(ProductSku::getSpecCombo, join)
|
|
|
- .orderByDesc(ProductSku::getCreateTime).last("limit 1");
|
|
|
+ .eq(ProductSku::getProductId, productId).orderByDesc(ProductSku::getCreateTime).last("limit 1");
|
|
|
ProductSku sku = productSkuMapper.selectOne(eq);
|
|
|
if (sku == null) {
|
|
|
vo.setImage("");
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
vo.setImage(sku.getImage());
|
|
|
+ vo.setPriceMoney(sku.getPriceMoney());
|
|
|
+ vo.setPricePoint(sku.getPricePoint());
|
|
|
+ vo.setOriginPrice(sku.getOriginPrice());
|
|
|
+ vo.setStock(sku.getStock());
|
|
|
}
|
|
|
vo.setSpecNameValueList(combo);
|
|
|
result.add(vo);
|
|
|
@@ -363,7 +526,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
|
|
* 计算笛卡尔积
|
|
|
*
|
|
|
* @param lists 规格值列表列表
|
|
|
- * @return List<List<T>> 笛卡尔积结果
|
|
|
+ * @return List<List < T>> 笛卡尔积结果
|
|
|
*/
|
|
|
private <T> List<List<T>> cartesianProduct(List<List<T>> lists) {
|
|
|
if (lists.isEmpty()) {
|