feature(uniapp分类): review

pull/2/head
luowenfeng 2022-10-17 19:55:46 +08:00
parent 8940375efa
commit 31f5b27d01
18 changed files with 142 additions and 158 deletions

View File

@ -24,9 +24,11 @@ public interface ErrorCodeConstants {
// ========== 商品规格名称 1008003000 ========== // ========== 商品规格名称 1008003000 ==========
ErrorCode PROPERTY_NOT_EXISTS = new ErrorCode(1008003000, "规格名称不存在"); ErrorCode PROPERTY_NOT_EXISTS = new ErrorCode(1008003000, "规格名称不存在");
ErrorCode PROPERTY_EXISTS = new ErrorCode(1008003001, "规格名称已存在");
// ========== 规格值 1008004000 ========== // ========== 规格值 1008004000 ==========
ErrorCode PROPERTY_VALUE_NOT_EXISTS = new ErrorCode(1008004000, "规格值不存在"); ErrorCode PROPERTY_VALUE_NOT_EXISTS = new ErrorCode(1008004000, "规格值不存在");
ErrorCode PROPERTY_VALUE_EXISTS = new ErrorCode(1008004001, "规格值已存在");
// ========== 商品 SPU 1008005000 ========== // ========== 商品 SPU 1008005000 ==========
ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在"); ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在");

View File

@ -56,7 +56,7 @@ public class ProductPropertyController {
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('product:property:query')") @PreAuthorize("@ss.hasPermission('product:property:query')")
public CommonResult<ProductPropertyRespVO> getProperty(@RequestParam("id") Long id) { public CommonResult<ProductPropertyRespVO> getProperty(@RequestParam("id") Long id) {
return success(productPropertyService.getPropertyResp(id)); return success(productPropertyService.getProperty(id));
} }
@GetMapping("/list") @GetMapping("/list")

View File

@ -55,9 +55,8 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO {
} }
// TODO @luowenfeng: 只返回 categoryId 可以么? 如果是为了前端修改时使用, 会拿到下拉列表, 自动选中合适的. 可以微信讨论下, 我也不完全确定哈;
@ApiModelProperty(value = "分类 id 数组,一直递归到一级父节点", example = "[1,2,4]") @ApiModelProperty(value = "分类 id 数组,一直递归到一级父节点", example = "[1,2,4]")
private List<Long> categoryIds; private Long categoryIds;
@ApiModelProperty(value = "规格属性修改和详情展示组合", example = "[{\"propertyId\":2,\"name\":\"内存\",\"propertyValues\":[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]},{\"propertyId\":3,\"name\":\"尺寸\",\"propertyValues\":[{\"v1\":16,\"v2\":\"6.1\"},{\"v1\":15,\"v2\":\"5.7\"}]}]") @ApiModelProperty(value = "规格属性修改和详情展示组合", example = "[{\"propertyId\":2,\"name\":\"内存\",\"propertyValues\":[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]},{\"propertyId\":3,\"name\":\"尺寸\",\"propertyValues\":[{\"v1\":16,\"v2\":\"6.1\"},{\"v1\":15,\"v2\":\"5.7\"}]}]")
private List<ProductPropertyViewRespVO> productPropertyViews; private List<ProductPropertyViewRespVO> productPropertyViews;

View File

@ -1,10 +1,13 @@
package cn.iocoder.yudao.module.product.convert.property; package cn.iocoder.yudao.module.product.convert.property;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyAndValueRespVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
@ -23,6 +26,8 @@ public interface ProductPropertyConvert {
ProductPropertyDO convert(ProductPropertyCreateReqVO bean); ProductPropertyDO convert(ProductPropertyCreateReqVO bean);
ProductPropertyDO convert(ProductPropertyUpdateReqVO bean); ProductPropertyDO convert(ProductPropertyUpdateReqVO bean);
ProductPropertyAndValueRespVO convert(ProductPropertyRespVO bean);
ProductPropertyRespVO convert(ProductPropertyDO bean); ProductPropertyRespVO convert(ProductPropertyDO bean);

View File

@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.Pro
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/** /**
* Mapper * Mapper
* *
@ -23,4 +25,9 @@ public interface ProductPropertyMapper extends BaseMapperX<ProductPropertyDO> {
.orderByDesc(ProductPropertyDO::getId)); .orderByDesc(ProductPropertyDO::getId));
} }
default ProductPropertyDO selectByName(String name) {
return selectOne(new LambdaQueryWrapperX<ProductPropertyDO>()
.likeIfPresent(ProductPropertyDO::getName, name));
}
} }

View File

@ -17,19 +17,20 @@ import java.util.List;
@Mapper @Mapper
public interface ProductPropertyValueMapper extends BaseMapperX<ProductPropertyValueDO> { public interface ProductPropertyValueMapper extends BaseMapperX<ProductPropertyValueDO> {
// TODO @luowenfeng方法名selectListByXXX。mapper 的操作都是 crud default List<ProductPropertyValueDO> selectListByPropertyValueListByPropertyId(List<Long> propertyIds) {
default List<ProductPropertyValueDO> getPropertyValueListByPropertyId(List<Long> propertyIds) {
// TODO @franky调用父类的 selectList
return selectList(new LambdaQueryWrapperX<ProductPropertyValueDO>() return selectList(new LambdaQueryWrapperX<ProductPropertyValueDO>()
.inIfPresent(ProductPropertyValueDO::getPropertyId, propertyIds)); .inIfPresent(ProductPropertyValueDO::getPropertyId, propertyIds));
} }
default ProductPropertyValueDO selectByName(Long propertyId, String name) {
return selectOne(new LambdaQueryWrapperX<ProductPropertyValueDO>()
.eq(ProductPropertyValueDO::getPropertyId, propertyId)
.eq(ProductPropertyValueDO::getName, name));
}
default void deletePropertyValueByPropertyId(Long propertyId) { default void deletePropertyValueByPropertyId(Long propertyId) {
// TODO @luowenfengdelete(new ) 即可 delete(new LambdaQueryWrapperX<ProductPropertyValueDO>().eq(ProductPropertyValueDO::getPropertyId, propertyId)
LambdaQueryWrapperX<ProductPropertyValueDO> queryWrapperX = new LambdaQueryWrapperX<>(); .eq(ProductPropertyValueDO::getDeleted, false));
queryWrapperX.eq(ProductPropertyValueDO::getPropertyId, propertyId)
.eq(ProductPropertyValueDO::getDeleted, false);
delete(queryWrapperX);
} }
default PageResult<ProductPropertyValueDO> selectPage(ProductPropertyValuePageReqVO reqVO) { default PageResult<ProductPropertyValueDO> selectPage(ProductPropertyValuePageReqVO reqVO) {

View File

@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.product.api.sku.dto.SkuDecrementStockBatchReqDTO; import cn.iocoder.yudao.module.product.api.sku.dto.SkuDecrementStockBatchReqDTO;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@ -17,20 +18,13 @@ import java.util.List;
@Mapper @Mapper
public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> { public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> {
// TODO @franky方法名 selectList; 可以直接调用 selectList
default List<ProductSkuDO> selectListBySpuIds(List<Long> spuIds) {
return selectList(ProductSkuDO::getSpuId, spuIds);
}
default List<ProductSkuDO> selectListBySpuId(Long spuId) { default List<ProductSkuDO> selectListBySpuId(Long spuId) {
return selectList(ProductSkuDO::getSpuId, spuId); return selectList(ProductSkuDO::getSpuId, spuId);
} }
default void deleteBySpuId(Long spuId) { default void deleteBySpuId(Long spuId) {
// TODO @franky直接 delete(new XXX) 即可,更简洁一些 delete(new LambdaQueryWrapperX<ProductSkuDO>()
LambdaQueryWrapperX<ProductSkuDO> lambdaQueryWrapperX = new LambdaQueryWrapperX<ProductSkuDO>() .eqIfPresent(ProductSkuDO::getSpuId, spuId));
.eqIfPresent(ProductSkuDO::getSpuId, spuId);
delete(lambdaQueryWrapperX);
} }
default void decrementStockBatch(List<SkuDecrementStockBatchReqDTO.Item> items) { default void decrementStockBatch(List<SkuDecrementStockBatchReqDTO.Item> items) {
@ -45,4 +39,7 @@ public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> {
this.update(null, lambdaUpdateWrapper); this.update(null, lambdaUpdateWrapper);
} }
} }
default List<ProductSkuDO> selectRemindSpuIds(){
return selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock"));
}
} }

View File

@ -93,18 +93,15 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
@Override @Override
public void validateCategoryLevel(Long id) { public void validateCategoryLevel(Long id) {
Long parentId = id; Long parentId = id;
for (int i = 0; i < 3; i++) { // TODO @luowenfeng: 建议还是先获得 level; 然后判断 level 是不是满足; 这样逻辑会更清晰一些; int i = 2;
if (Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL)) { for (; i >= 0; --i) {
throw exception(CATEGORY_LEVEL_ERROR);
}
ProductCategoryDO category = productCategoryMapper.selectById(parentId); ProductCategoryDO category = productCategoryMapper.selectById(parentId);
if (category == null) {
// TODO @luowenfeng: 应该抛出 CATEGORY_LEVEL_ERROR
throw exception(CATEGORY_NOT_EXISTS);
}
parentId = category.getParentId(); parentId = category.getParentId();
if(Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL)){
break;
}
} }
if (!Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL)) { if (!Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL) || i != 0) {
throw exception(CATEGORY_LEVEL_ERROR); throw exception(CATEGORY_LEVEL_ERROR);
} }
} }

View File

@ -38,14 +38,6 @@ public interface ProductPropertyService {
*/ */
void deleteProperty(Long id); void deleteProperty(Long id);
/**
*
*
* @param id
* @return
*/
ProductPropertyDO getProperty(Long id);
/** /**
* *
* @param listReqVO * @param listReqVO
@ -61,8 +53,12 @@ public interface ProductPropertyService {
*/ */
PageResult<ProductPropertyRespVO> getPropertyPage(ProductPropertyPageReqVO pageReqVO); PageResult<ProductPropertyRespVO> getPropertyPage(ProductPropertyPageReqVO pageReqVO);
// TODO luowenfeng: getProperty 就可以拉, 不用到 Resp /**
ProductPropertyRespVO getPropertyResp(Long id); *
* @param id
* @return
*/
ProductPropertyRespVO getProperty(Long id);
/** /**
* + * +

View File

@ -1,13 +1,10 @@
package cn.iocoder.yudao.module.product.service.property; package cn.iocoder.yudao.module.product.service.property;
import cn.hutool.core.bean.BeanUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*; import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
import cn.iocoder.yudao.module.product.convert.property.ProductPropertyConvert; import cn.iocoder.yudao.module.product.convert.property.ProductPropertyConvert;
import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert; import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
@ -19,13 +16,12 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_EXISTS;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_NOT_EXISTS; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_NOT_EXISTS;
/** /**
@ -46,7 +42,10 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Long createProperty(ProductPropertyCreateReqVO createReqVO) { public Long createProperty(ProductPropertyCreateReqVO createReqVO) {
// TODO @luowenfeng: 插入和更新的时候, 要校验 name 的唯一性; // 校验存在
if(productPropertyMapper.selectByName(createReqVO.getName()) != null){
throw exception(PROPERTY_EXISTS);
}
// 插入 // 插入
ProductPropertyDO property = ProductPropertyConvert.INSTANCE.convert(createReqVO); ProductPropertyDO property = ProductPropertyConvert.INSTANCE.convert(createReqVO);
productPropertyMapper.insert(property); productPropertyMapper.insert(property);
@ -59,6 +58,9 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
public void updateProperty(ProductPropertyUpdateReqVO updateReqVO) { public void updateProperty(ProductPropertyUpdateReqVO updateReqVO) {
// 校验存在 // 校验存在
this.validatePropertyExists(updateReqVO.getId()); this.validatePropertyExists(updateReqVO.getId());
if(productPropertyMapper.selectByName(updateReqVO.getName()) != null){
throw exception(PROPERTY_EXISTS);
}
// 更新 // 更新
ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO); ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO);
productPropertyMapper.updateById(updateObj); productPropertyMapper.updateById(updateObj);
@ -80,11 +82,6 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
} }
} }
@Override
public ProductPropertyDO getProperty(Long id) {
return productPropertyMapper.selectById(id);
}
@Override @Override
public List<ProductPropertyRespVO> getPropertyList(ProductPropertyListReqVO listReqVO) { public List<ProductPropertyRespVO> getPropertyList(ProductPropertyListReqVO listReqVO) {
return ProductPropertyConvert.INSTANCE.convertList(productPropertyMapper.selectList(new LambdaQueryWrapperX<ProductPropertyDO>() return ProductPropertyConvert.INSTANCE.convertList(productPropertyMapper.selectList(new LambdaQueryWrapperX<ProductPropertyDO>()
@ -96,29 +93,16 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
public PageResult<ProductPropertyRespVO> getPropertyPage(ProductPropertyPageReqVO pageReqVO) { public PageResult<ProductPropertyRespVO> getPropertyPage(ProductPropertyPageReqVO pageReqVO) {
//获取属性列表 //获取属性列表
PageResult<ProductPropertyDO> pageResult = productPropertyMapper.selectPage(pageReqVO); PageResult<ProductPropertyDO> pageResult = productPropertyMapper.selectPage(pageReqVO);
PageResult<ProductPropertyRespVO> propertyRespVOPageResult = ProductPropertyConvert.INSTANCE.convertPage(pageResult); return ProductPropertyConvert.INSTANCE.convertPage(pageResult);
// TODO @luofengwen: 下面的代码, 如果不要,可以删除哈; git 可以拿到记录的
// List<Long> propertyIds = propertyRespVOPageResult.getList().stream().map(ProductPropertyAndValueRespVO::getId).collect(Collectors.toList());
//
// //获取属性值列表
// List<ProductPropertyValueDO> productPropertyValueDOList = productPropertyValueMapper.getPropertyValueListByPropertyId(propertyIds);
// List<ProductPropertyValueRespVO> propertyValueRespVOList = ProductPropertyValueConvert.INSTANCE.convertList(productPropertyValueDOList);
// //组装一对多
// propertyRespVOPageResult.getList().forEach(x->{
// Long propertyId = x.getId();
// List<ProductPropertyValueRespVO> valueDOList = propertyValueRespVOList.stream().filter(v -> v.getPropertyId().equals(propertyId)).collect(Collectors.toList());
// x.setValues(valueDOList);
// });
return propertyRespVOPageResult;
} }
private List<ProductPropertyValueDO> getPropertyValueListByPropertyId(List<Long> propertyIds) { private List<ProductPropertyValueDO> getPropertyValueListByPropertyId(List<Long> propertyIds) {
return productPropertyValueMapper.getPropertyValueListByPropertyId(propertyIds); return productPropertyValueMapper.selectListByPropertyValueListByPropertyId(propertyIds);
} }
@Override @Override
public ProductPropertyRespVO getPropertyResp(Long id) { public ProductPropertyRespVO getProperty(Long id) {
ProductPropertyDO property = getProperty(id); ProductPropertyDO property = productPropertyMapper.selectById(id);
return ProductPropertyConvert.INSTANCE.convert(property); return ProductPropertyConvert.INSTANCE.convert(property);
} }
@ -132,17 +116,12 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
List<ProductPropertyRespVO> propertyList = getPropertyList(listReqVO); List<ProductPropertyRespVO> propertyList = getPropertyList(listReqVO);
// 查询属性值 // 查询属性值
List<ProductPropertyValueDO> valueDOList = productPropertyValueMapper.getPropertyValueListByPropertyId(CollectionUtils.convertList(propertyList, ProductPropertyRespVO::getId)); List<ProductPropertyValueDO> valueDOList = productPropertyValueMapper.selectListByPropertyValueListByPropertyId(CollectionUtils.convertList(propertyList, ProductPropertyRespVO::getId));
// CollectionUtils.convertMultiMap() // TODO @luofengwen: 可以使用这个方法哈 Map<Long, List<ProductPropertyValueDO>> valueDOMap = CollectionUtils.convertMultiMap(valueDOList, ProductPropertyValueDO::getPropertyId);
Map<Long, List<ProductPropertyValueRespVO>> valueDOMap = valueDOList.stream() return CollectionUtils.convertList(propertyList, m -> {
.map(ProductPropertyValueConvert.INSTANCE::convert) ProductPropertyAndValueRespVO productPropertyAndValueRespVO = ProductPropertyConvert.INSTANCE.convert(m);
.collect(Collectors.groupingBy(ProductPropertyValueRespVO::getPropertyId)); productPropertyAndValueRespVO.setValues(ProductPropertyValueConvert.INSTANCE.convertList(valueDOMap.get(m.getId())));
// 组装 TODO @luowenfeng: CollectionUtils 转换哈;
return propertyList.stream().map(m -> {
// TODO @luowenfeng: 使用 mapstruct convert 哈
ProductPropertyAndValueRespVO productPropertyAndValueRespVO = BeanUtil.copyProperties(m, ProductPropertyAndValueRespVO.class);
productPropertyAndValueRespVO.setValues(valueDOMap.get(m.getId()));
return productPropertyAndValueRespVO; return productPropertyAndValueRespVO;
}).collect(Collectors.toList()); });
} }
} }

View File

@ -10,7 +10,7 @@ import java.util.List;
/** /**
* <p> * <p>
* * Service
* </p> * </p>
* *
* @author LuoWenFeng * @author LuoWenFeng

View File

@ -15,9 +15,12 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_EXISTS;
/** /**
* <p> TODO @luowenfeng: * <p>
* * Service
* </p> * </p>
* *
* @author LuoWenFeng * @author LuoWenFeng
@ -31,7 +34,9 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ
@Override @Override
public Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO) { public Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO) {
// TODO @luowenfeng: 需要校验下在这个 propertyId, 新增和更新, name 都要唯一 if (productPropertyValueMapper.selectByName(createReqVO.getPropertyId(), createReqVO.getName()) != null) {
throw exception(PROPERTY_VALUE_EXISTS);
}
ProductPropertyValueDO convert = ProductPropertyValueConvert.INSTANCE.convert(createReqVO); ProductPropertyValueDO convert = ProductPropertyValueConvert.INSTANCE.convert(createReqVO);
productPropertyValueMapper.insert(convert); productPropertyValueMapper.insert(convert);
return convert.getId(); return convert.getId();
@ -39,6 +44,9 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ
@Override @Override
public void updatePropertyValue(ProductPropertyValueUpdateReqVO updateReqVO) { public void updatePropertyValue(ProductPropertyValueUpdateReqVO updateReqVO) {
if (productPropertyValueMapper.selectByName(updateReqVO.getPropertyId(), updateReqVO.getName()) != null) {
throw exception(PROPERTY_VALUE_EXISTS);
}
ProductPropertyValueDO convert = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO); ProductPropertyValueDO convert = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO);
productPropertyValueMapper.updateById(convert); productPropertyValueMapper.updateById(convert);
} }

View File

@ -83,12 +83,11 @@ public interface ProductSkuService {
*/ */
void deleteSkuBySpuId(Long spuId); void deleteSkuBySpuId(Long spuId);
// TODO @luowenfeng: 可以改成返回 ProductSkuDO 列表; 然后, 上层业务在做处理;
/** /**
* SPU * SPU
* *
* @return spuId * @return spuId
*/ */
List<Long> getRemindSpuIds(); List<ProductSkuDO> getRemindSpuIds();
} }

View File

@ -124,12 +124,12 @@ public class ProductSkuServiceImpl implements ProductSkuService {
@Override @Override
public List<ProductSkuDO> getSkusBySpuId(Long spuId) { public List<ProductSkuDO> getSkusBySpuId(Long spuId) {
return productSkuMapper.selectListBySpuIds(Collections.singletonList(spuId)); return productSkuMapper.selectList(ProductSkuDO::getSpuId, spuId);
} }
@Override @Override
public List<ProductSkuDO> getSkusBySpuIds(List<Long> spuIds) { public List<ProductSkuDO> getSkusBySpuIds(List<Long> spuIds) {
return productSkuMapper.selectListBySpuIds(spuIds); return productSkuMapper.selectList(ProductSkuDO::getSpuId, spuIds);
} }
@Override @Override
@ -138,10 +138,8 @@ public class ProductSkuServiceImpl implements ProductSkuService {
} }
@Override @Override
public List<Long> getRemindSpuIds() { public List<ProductSkuDO> getRemindSpuIds() {
// TODO @luowenfeng: mybatis plus 不能出现在 Service 哈; 把这个查询, 下沉一个方法到 mapper 里 return productSkuMapper.selectRemindSpuIds();
List<ProductSkuDO> productSkuDOS = productSkuMapper.selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock"));
return productSkuDOS.stream().map(ProductSkuDO::getSpuId).distinct().collect(Collectors.toList());
} }
@Override @Override
@ -160,12 +158,6 @@ public class ProductSkuServiceImpl implements ProductSkuService {
return String.join("-", collect, String.valueOf(v.getId())); return String.join("-", collect, String.valueOf(v.getId()));
}) })
.collect(Collectors.toMap(v -> v.split("-")[0], v -> Long.valueOf(v.split("-")[1]))); .collect(Collectors.toMap(v -> v.split("-")[0], v -> Long.valueOf(v.split("-")[1])));
// Map<String, Long> existsSkuMap2 = CollectionUtils.convertMap(existsSkus, productSkuDO -> {
// if (CollUtil.isEmpty(productSkuDO.getProperties())) {
// return "";
// }
// return StrUtil.join("-", convertList(productSkuDO.getProperties(), ProductSkuDO.Property::getValueId));
// }, ProductSkuDO::getId);
// 拆分三个集合,新插入的、需要更新的、需要删除的 // 拆分三个集合,新插入的、需要更新的、需要删除的
List<ProductSkuDO> insertSkus = new ArrayList<>(); List<ProductSkuDO> insertSkus = new ArrayList<>();

View File

@ -72,7 +72,7 @@ public interface ProductSpuService {
PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO); PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO);
/** /**
* SPU // TODO @luowenfeng: 中文和英文之间, 要有一个空格; 这样, 阅读起来会更清晰; 我已经都改啦 * SPU
* *
* @param pageReqVO * @param pageReqVO
* @return spu * @return spu

View File

@ -14,6 +14,7 @@ import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
@ -134,7 +135,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
List<ProductSpuDetailRespVO.Sku> skuReqs = ProductSkuConvert.INSTANCE.convertList03(productSkuService.getSkusBySpuId(id)); List<ProductSpuDetailRespVO.Sku> skuReqs = ProductSkuConvert.INSTANCE.convertList03(productSkuService.getSkusBySpuId(id));
respVO.setSkus(skuReqs); respVO.setSkus(skuReqs);
// 组合 sku 规格属性 // 组合 sku 规格属性
if(spu.getSpecType().equals(ProductSpuSpecTypeEnum.DISABLE.getType())) { if (spu.getSpecType().equals(ProductSpuSpecTypeEnum.DISABLE.getType())) {
List<ProductSkuRespVO.Property> properties = new ArrayList<>(); List<ProductSkuRespVO.Property> properties = new ArrayList<>();
for (ProductSpuDetailRespVO.Sku productSkuRespVO : skuReqs) { for (ProductSpuDetailRespVO.Sku productSkuRespVO : skuReqs) {
properties.addAll(productSkuRespVO.getProperties()); properties.addAll(productSkuRespVO.getProperties());
@ -162,18 +163,19 @@ public class ProductSpuServiceImpl implements ProductSpuService {
respVO.setProductPropertyViews(productPropertyViews); respVO.setProductPropertyViews(productPropertyViews);
} }
// 组合分类 // 组合分类
if (null != respVO.getCategoryId()) { // if (null != respVO.getCategoryId()) {
LinkedList<Long> categoryArray = new LinkedList<>(); // LinkedList<Long> categoryArray = new LinkedList<>();
Long parentId = respVO.getCategoryId(); // Long parentId = respVO.getCategoryId();
categoryArray.addFirst(parentId); // categoryArray.addFirst(parentId);
while (parentId != 0) { // while (parentId != 0) {
parentId = categoryService.getCategory(parentId).getParentId(); // parentId = categoryService.getCategory(parentId).getParentId();
if (parentId > 0) { // if (parentId > 0) {
categoryArray.addFirst(parentId); // categoryArray.addFirst(parentId);
} // }
} // }
respVO.setCategoryIds(categoryArray); //
} // }
respVO.setCategoryIds(respVO.getCategoryId());
} }
return respVO; return respVO;
} }
@ -190,12 +192,10 @@ public class ProductSpuServiceImpl implements ProductSpuService {
@Override @Override
public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) { public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) {
List<Long> remindSpuIds= null; List<Long> remindSpuIds = null;
// todo @yunai 预警类型的判断应该可以优化,看下怎么处理 if (pageReqVO.getTabStatus() != null && pageReqVO.getTabStatus() == 2) {
// TODO @luowenfeng: 先这么简单处理; 性能应该影响不大的; remindSpuIds = productSkuService.getRemindSpuIds().stream().map(ProductSkuDO::getSpuId).distinct().collect(Collectors.toList());
if(pageReqVO.getTabStatus() != null && pageReqVO.getTabStatus() == 2){ if (remindSpuIds.isEmpty()) {
remindSpuIds= productSkuService.getRemindSpuIds();
if(remindSpuIds.isEmpty()){
remindSpuIds.add(null); remindSpuIds.add(null);
} }
} }

View File

@ -1,19 +1,19 @@
package cn.iocoder.yudao.module.pay.api.order; //package cn.iocoder.yudao.module.pay.api.order;
//
import org.springframework.stereotype.Service; //import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; //import org.springframework.transaction.annotation.Transactional;
//
/** ///**
* @author LeeYan9 // * @author LeeYan9
* @since 2022-09-06 // * @since 2022-09-06
*/ // */
@Service //@Service
public class PayOrderApiImpl implements PayOrderApi { //public class PayOrderApiImpl implements PayOrderApi {
//
@Override // @Override
@Transactional(rollbackFor = Exception.class) // @Transactional(rollbackFor = Exception.class)
public Long createPayOrder(PayOrderInfoCreateReqDTO reqDTO) { // public Long createPayOrder(PayOrderInfoCreateReqDTO reqDTO) {
return null; // return null;
} // }
//
} //}

View File

@ -39,8 +39,7 @@
<el-tab-pane label="价格库存" name="rates" class="rates"> <el-tab-pane label="价格库存" name="rates" class="rates">
<el-form ref="rates" :model="ratesForm" :rules="rules"> <el-form ref="rates" :model="ratesForm" :rules="rules">
<el-form-item label="启用多规格"> <el-form-item label="启用多规格">
<!-- TODO @luowenfeng: 1) activeSwitch 可以考虑改成; specSwitch, 更清晰一点, activeSwitch 太通用了; changeRadio 改成 changeSpecSwitch --> <el-switch v-model="specSwitch" @change="changeSpecSwitch"></el-switch>
<el-switch v-model="activeSwitch" @change="changeRadio"></el-switch>
</el-form-item> </el-form-item>
<!-- 动态添加规格属性 --> <!-- 动态添加规格属性 -->
@ -67,7 +66,7 @@
<!-- 规格明细 --> <!-- 规格明细 -->
<el-form-item label="规格明细"> <el-form-item label="规格明细">
<el-table :data="ratesForm.rates" border style="width: 100%" ref="ratesTable"> <el-table :data="ratesForm.rates" border style="width: 100%" ref="ratesTable">
<template v-if="this.activeSwitch"> <template v-if="this.specSwitch">
<el-table-column :key="index" v-for="(item, index) in dynamicSpec.filter(v => v.specName !== undefined)" <el-table-column :key="index" v-for="(item, index) in dynamicSpec.filter(v => v.specName !== undefined)"
:label="item.specName"> :label="item.specName">
<template slot-scope="scope"> <template slot-scope="scope">
@ -81,7 +80,7 @@
style="width: 100px; height: 50px"/> style="width: 100px; height: 50px"/>
</template> </template>
</el-table-column> </el-table-column>
<template v-if="this.activeSwitch"> <template v-if="this.specSwitch">
<el-table-column label="sku名称" :render-header="addRedStar" key="91"> <el-table-column label="sku名称" :render-header="addRedStar" key="91">
<template slot-scope="scope"> <template slot-scope="scope">
<el-form-item :prop="'rates.'+ scope.$index + '.name'" <el-form-item :prop="'rates.'+ scope.$index + '.name'"
@ -148,13 +147,13 @@
<el-input v-model="scope.row.barCode"></el-input> <el-input v-model="scope.row.barCode"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<template v-if="this.activeSwitch"> <template v-if="this.specSwitch">
<el-table-column fixed="right" label="操作" width="50" key="100"> <el-table-column fixed="right" label="操作" width="50" key="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button @click="scope.row.status = 1" type="text" size="small" <el-button @click="scope.row.status = 1" type="text" size="small"
v-show="scope.row.status == undefined || scope.row.status == 0 ">禁用 v-show="scope.row.status === undefined || scope.row.status === 0 ">禁用
</el-button> </el-button>
<el-button @click="scope.row.status = 0" type="text" size="small" v-show="scope.row.status == 1"> <el-button @click="scope.row.status = 0" type="text" size="small" v-show="scope.row.status === 1">
启用 启用
</el-button> </el-button>
</template> </template>
@ -220,7 +219,7 @@ export default {
}, },
data() { data() {
return { return {
activeSwitch: false, specSwitch: false,
activeName: "base", activeName: "base",
propName: { propName: {
checkStrictly: true, checkStrictly: true,
@ -287,7 +286,7 @@ export default {
methods: { methods: {
removeSpec(index) { removeSpec(index) {
this.dynamicSpec.splice(index, 1); this.dynamicSpec.splice(index, 1);
this.changeRadio() this.changeSpecSwitch()
}, },
// //
addRedStar(h, {column}) { addRedStar(h, {column}) {
@ -296,10 +295,10 @@ export default {
h('span', ' ' + column.label) h('span', ' ' + column.label)
]; ];
}, },
changeRadio() { changeSpecSwitch() {
this.activeSwitch ? this.ratesForm.spec = 2 : this.ratesForm.spec = 1; this.specSwitch ? this.ratesForm.spec = 2 : this.ratesForm.spec = 1;
this.$refs.ratesTable.doLayout(); this.$refs.ratesTable.doLayout();
if (this.ratesForm.spec == 1) { if (this.ratesForm.spec === 1) {
this.ratesForm.rates = [{}] this.ratesForm.rates = [{}]
} else { } else {
this.ratesForm.rates = [] this.ratesForm.rates = []
@ -380,7 +379,7 @@ export default {
}) })
// //
if (this.activeSwitch) { if (this.specSwitch) {
rates.forEach(r => { rates.forEach(r => {
let properties = [] let properties = []
Array.of(r.spec).forEach(s => { Array.of(r.spec).forEach(s => {
@ -391,7 +390,7 @@ export default {
obj = Array.of(s); obj = Array.of(s);
} }
obj.forEach((v, i) => { obj.forEach((v, i) => {
let specValue = this.dynamicSpec[i].specValue.find(o => o.name == v); let specValue = this.dynamicSpec[i].specValue.find(o => o.name === v);
let propertie = {}; let propertie = {};
propertie.propertyId = this.dynamicSpec[i].specId; propertie.propertyId = this.dynamicSpec[i].specId;
propertie.valueId = specValue.id; propertie.valueId = specValue.id;
@ -414,17 +413,20 @@ export default {
} }
form.skus = rates; form.skus = rates;
form.specType = this.ratesForm.spec; form.specType = this.ratesForm.spec;
form.categoryId = form.categoryIds[this.baseForm.categoryIds.length - 1];
let category = form.categoryIds instanceof Array ? form.categoryIds: Array.of(form.categoryIds)
console.log(category)
form.categoryId = category[category.length - 1];
if (form.id == null) { if (form.id == null) {
createSpu(form).then((response) => { createSpu(form).then(() => {
this.$modal.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
}) })
.then(()=>{ .then(()=>{
this.cancel(); this.cancel();
}) })
} else { } else {
updateSpu(form).then((response) => { updateSpu(form).then(() => {
this.$modal.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
}) })
.then(()=>{ .then(()=>{
@ -443,8 +445,8 @@ export default {
}, },
// //
changeSpec(val) { changeSpec(val) {
let obj = this.propertyPageList.find(o => o.id == val); let obj = this.propertyPageList.find(o => o.id === val);
let spec = this.dynamicSpec.find(o => o.specId == val) let spec = this.dynamicSpec.find(o => o.specId === val)
spec.specId = obj.id; spec.specId = obj.id;
spec.specName = obj.name; spec.specName = obj.name;
spec.specValue = obj.values; spec.specValue = obj.values;
@ -471,8 +473,8 @@ export default {
r.price = this.divide(r.price, 100) r.price = this.divide(r.price, 100)
r.costPrice = this.divide(r.costPrice, 100) r.costPrice = this.divide(r.costPrice, 100)
}) })
if (this.ratesForm.spec == 2) { if (this.ratesForm.spec === 2) {
this.activeSwitch = true; this.specSwitch = true;
data.productPropertyViews.forEach(p => { data.productPropertyViews.forEach(p => {
let obj = {}; let obj = {};
obj.specId = p.propertyId; obj.specId = p.propertyId;
@ -483,7 +485,7 @@ export default {
data.skus.forEach(s => { data.skus.forEach(s => {
s.spec = []; s.spec = [];
s.properties.forEach(sp => { s.properties.forEach(sp => {
let spec = data.productPropertyViews.find(o => o.propertyId == sp.propertyId).propertyValues.find(v => v.id == sp.valueId).name; let spec = data.productPropertyViews.find(o => o.propertyId === sp.propertyId).propertyValues.find(v => v.id === sp.valueId).name;
s.spec.push(spec) s.spec.push(spec)
}) })
}) })