mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 15:21:53 +08:00
mall + product:完善商品详情接口
This commit is contained in:
parent
dd93215139
commit
f75f4e8846
@ -57,6 +57,11 @@ public class DictFrameworkUtils {
|
|||||||
log.info("[init][初始化 DictFrameworkUtils 成功]");
|
log.info("[init][初始化 DictFrameworkUtils 成功]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public static String getDictDataLabel(String dictType, Integer value) {
|
||||||
|
return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, String.valueOf(value))).getLabel();
|
||||||
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public static String getDictDataLabel(String dictType, String value) {
|
public static String getDictDataLabel(String dictType, String value) {
|
||||||
return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, value)).getLabel();
|
return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, value)).getLabel();
|
||||||
|
@ -35,10 +35,9 @@
|
|||||||
<groupId>cn.iocoder.boot</groupId>
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
|
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- TODO 芋艿:是不是可以去掉这个依赖呀? -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
|
<artifactId>yudao-spring-boot-starter-biz-dict</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Web 相关 -->
|
<!-- Web 相关 -->
|
||||||
|
@ -5,13 +5,11 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|||||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
|
||||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO;
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO;
|
||||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
|
||||||
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.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.enums.spu.ProductSpuStatusEnum;
|
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
|
||||||
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
|
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
|
||||||
import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
|
|
||||||
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
|
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
|
||||||
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
|
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@ -67,11 +65,8 @@ public class AppProductSpuController {
|
|||||||
|
|
||||||
// 查询商品 SKU
|
// 查询商品 SKU
|
||||||
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
|
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
|
||||||
// 查询商品属性
|
|
||||||
List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
|
|
||||||
.getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
|
|
||||||
// 拼接
|
// 拼接
|
||||||
return success(ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus, propertyValues));
|
return success(ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,9 @@ public class AppProductSpuDetailRespVO {
|
|||||||
@Schema(description = "商品视频", required = true)
|
@Schema(description = "商品视频", required = true)
|
||||||
private String videoUrl;
|
private String videoUrl;
|
||||||
|
|
||||||
|
@Schema(description = "单位名", required = true, example = "个")
|
||||||
|
private String unitName;
|
||||||
|
|
||||||
// ========== SKU 相关字段 =========
|
// ========== SKU 相关字段 =========
|
||||||
|
|
||||||
@Schema(description = "规格类型", required = true, example = "true")
|
@Schema(description = "规格类型", required = true, example = "true")
|
||||||
@ -47,6 +50,9 @@ public class AppProductSpuDetailRespVO {
|
|||||||
@Schema(description = "市场价,单位使用:分", required = true, example = "1024")
|
@Schema(description = "市场价,单位使用:分", required = true, example = "1024")
|
||||||
private Integer marketPrice;
|
private Integer marketPrice;
|
||||||
|
|
||||||
|
@Schema(description = "VIP 价格,单位使用:分", required = true, example = "968") // 通过会员等级,计算出折扣后价格
|
||||||
|
private Integer vipPrice;
|
||||||
|
|
||||||
@Schema(description = "库存", required = true, example = "666")
|
@Schema(description = "库存", required = true, example = "666")
|
||||||
private Integer stock;
|
private Integer stock;
|
||||||
|
|
||||||
@ -78,6 +84,9 @@ public class AppProductSpuDetailRespVO {
|
|||||||
@Schema(description = "市场价,单位使用:分", required = true, example = "1024")
|
@Schema(description = "市场价,单位使用:分", required = true, example = "1024")
|
||||||
private Integer marketPrice;
|
private Integer marketPrice;
|
||||||
|
|
||||||
|
@Schema(description = "VIP 价格,单位使用:分", required = true, example = "968") // 通过会员等级,计算出折扣后价格
|
||||||
|
private Integer vipPrice;
|
||||||
|
|
||||||
@Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png")
|
@Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png")
|
||||||
private String picUrl;
|
private String picUrl;
|
||||||
|
|
||||||
@ -89,6 +98,7 @@ public class AppProductSpuDetailRespVO {
|
|||||||
|
|
||||||
@Schema(description = "商品体积", example = "1024") // 单位:m^3 平米
|
@Schema(description = "商品体积", example = "1024") // 单位:m^3 平米
|
||||||
private Double volume;
|
private Double volume;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -68,16 +68,6 @@ public interface ProductSkuConvert {
|
|||||||
return spuIdAndStockMap;
|
return spuIdAndStockMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
default Collection<Long> convertPropertyValueIds(List<ProductSkuDO> list) {
|
|
||||||
if (CollUtil.isEmpty(list)) {
|
|
||||||
return new HashSet<>();
|
|
||||||
}
|
|
||||||
return list.stream().filter(item -> item.getProperties() != null)
|
|
||||||
.flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性
|
|
||||||
.map(ProductSkuDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId,最后形成集合
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
default String buildPropertyKey(ProductSkuDO bean) {
|
default String buildPropertyKey(ProductSkuDO bean) {
|
||||||
if (CollUtil.isEmpty(bean.getProperties())) {
|
if (CollUtil.isEmpty(bean.getProperties())) {
|
||||||
return StrUtil.EMPTY;
|
return StrUtil.EMPTY;
|
||||||
|
@ -3,17 +3,17 @@ package cn.iocoder.yudao.module.product.convert.spu;
|
|||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
|
||||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
|
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
||||||
import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
|
|
||||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
|
||||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO;
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO;
|
||||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
|
||||||
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
|
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
|
||||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
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.service.property.bo.ProductPropertyValueDetailRespBO;
|
import cn.iocoder.yudao.module.product.enums.DictTypeConstants;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.Mapping;
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.Named;
|
import org.mapstruct.Named;
|
||||||
@ -21,10 +21,8 @@ import org.mapstruct.factory.Mappers;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static cn.hutool.core.util.ObjectUtil.defaultIfNull;
|
import static cn.hutool.core.util.ObjectUtil.defaultIfNull;
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品 SPU Convert
|
* 商品 SPU Convert
|
||||||
@ -91,28 +89,17 @@ public interface ProductSpuConvert {
|
|||||||
|
|
||||||
PageResult<AppProductSpuPageItemRespVO> convertPageForGetSpuPage0(PageResult<ProductSpuDO> page);
|
PageResult<AppProductSpuPageItemRespVO> convertPageForGetSpuPage0(PageResult<ProductSpuDO> page);
|
||||||
|
|
||||||
default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List<ProductSkuDO> skus,
|
default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List<ProductSkuDO> skus) {
|
||||||
List<ProductPropertyValueDetailRespBO> propertyValues) {
|
// 处理 SPU
|
||||||
AppProductSpuDetailRespVO spuVO = convertForGetSpuDetail(spu)
|
AppProductSpuDetailRespVO spuVO = convertForGetSpuDetail(spu)
|
||||||
.setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0));
|
.setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0))
|
||||||
|
.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit()));
|
||||||
|
// 处理 SKU
|
||||||
spuVO.setSkus(convertListForGetSpuDetail(skus));
|
spuVO.setSkus(convertListForGetSpuDetail(skus));
|
||||||
// 处理商品属性
|
// 计算 vip 价格 TODO 芋艿:临时的逻辑,等 vip 支持后
|
||||||
Map<Long, ProductPropertyValueDetailRespBO> propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId);
|
if (true) {
|
||||||
for (int i = 0; i < skus.size(); i++) {
|
spuVO.setVipPrice((int) (spuVO.getPrice() * 0.9));
|
||||||
List<ProductSkuDO.Property> properties = skus.get(i).getProperties();
|
spuVO.getSkus().forEach(sku -> sku.setVipPrice((int) (sku.getPrice() * 0.9)));
|
||||||
if (CollUtil.isEmpty(properties)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
AppProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i);
|
|
||||||
sku.setProperties(new ArrayList<>(properties.size()));
|
|
||||||
// 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中
|
|
||||||
properties.forEach(property -> {
|
|
||||||
ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId());
|
|
||||||
if (propertyValue == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sku.getProperties().add(convertForGetSpuDetail(propertyValue));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return spuVO;
|
return spuVO;
|
||||||
}
|
}
|
||||||
@ -121,8 +108,6 @@ public interface ProductSpuConvert {
|
|||||||
|
|
||||||
List<AppProductSpuDetailRespVO.Sku> convertListForGetSpuDetail(List<ProductSkuDO> skus);
|
List<AppProductSpuDetailRespVO.Sku> convertListForGetSpuDetail(List<ProductSkuDO> skus);
|
||||||
|
|
||||||
AppProductPropertyValueDetailRespVO convertForGetSpuDetail(ProductPropertyValueDetailRespBO propertyValue);
|
|
||||||
|
|
||||||
default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List<ProductSkuDO> skus) {
|
default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List<ProductSkuDO> skus) {
|
||||||
ProductSpuDetailRespVO productSpuDetailRespVO = convert03(spu);
|
ProductSpuDetailRespVO productSpuDetailRespVO = convert03(spu);
|
||||||
// skus 为空直接返回
|
// skus 为空直接返回
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.product.dal.dataobject.property;
|
package cn.iocoder.yudao.module.product.dal.dataobject.property;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
|
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.product.dal.dataobject.property;
|
package cn.iocoder.yudao.module.product.dal.dataobject.property;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
|
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
|
|||||||
import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
|
import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
|
||||||
import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
|
import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
|
||||||
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
|
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@ -238,17 +239,22 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Integer, Long> getTabsCount() {
|
public Map<Integer, Long> getTabsCount() {
|
||||||
Map<Integer, Long> counts = new HashMap<>(5);
|
Map<Integer, Long> counts = Maps.newLinkedHashMapWithExpectedSize(5);
|
||||||
// 查询销售中的商品数量
|
// 查询销售中的商品数量
|
||||||
counts.put(ProductSpuPageReqVO.FOR_SALE, productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()));
|
counts.put(ProductSpuPageReqVO.FOR_SALE,
|
||||||
|
productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()));
|
||||||
// 查询仓库中的商品数量
|
// 查询仓库中的商品数量
|
||||||
counts.put(ProductSpuPageReqVO.IN_WAREHOUSE, productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus()));
|
counts.put(ProductSpuPageReqVO.IN_WAREHOUSE,
|
||||||
|
productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus()));
|
||||||
// 查询售空的商品数量
|
// 查询售空的商品数量
|
||||||
counts.put(ProductSpuPageReqVO.SOLD_OUT, productSpuMapper.selectCount(ProductSpuDO::getStock, 0));
|
counts.put(ProductSpuPageReqVO.SOLD_OUT,
|
||||||
|
productSpuMapper.selectCount(ProductSpuDO::getStock, 0));
|
||||||
// 查询触发警戒库存的商品数量
|
// 查询触发警戒库存的商品数量
|
||||||
counts.put(ProductSpuPageReqVO.ALERT_STOCK, productSpuMapper.selectCount());
|
counts.put(ProductSpuPageReqVO.ALERT_STOCK,
|
||||||
|
productSpuMapper.selectCount());
|
||||||
// 查询回收站中的商品数量
|
// 查询回收站中的商品数量
|
||||||
counts.put(ProductSpuPageReqVO.RECYCLE_BIN, productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()));
|
counts.put(ProductSpuPageReqVO.RECYCLE_BIN,
|
||||||
|
productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()));
|
||||||
return counts;
|
return counts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user