商品模块代码提交

This commit is contained in:
Tankaikai 2025-02-19 19:48:33 +08:00
parent 4ae8d71866
commit 6e29494fc7
8 changed files with 316 additions and 7 deletions

View File

@ -2,13 +2,16 @@ package com.czg.controller.user;
import com.czg.log.annotation.OperationLog;
import com.czg.product.param.MiniHomeProductParam;
import com.czg.product.param.ShopProductSkuParam;
import com.czg.product.service.UProductService;
import com.czg.product.vo.MiniAppHomeProductVo;
import com.czg.product.vo.ShopGroupProductVo;
import com.czg.product.vo.ShopProductVo;
import com.czg.product.vo.*;
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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -58,4 +61,28 @@ public class UProductController {
return CzgResult.success(list);
}
/**
* 小程序点餐-商品详情
*
* @param id 商品id
*/
@GetMapping("/miniApp/info/{id}")
@OperationLog("小程序点餐-商品详情")
public CzgResult<ShopProductInfoVo> getProductInfo(@PathVariable("id") Long id) {
AssertUtil.isNull(id, "商品id不能为空");
ShopProductInfoVo data = uProductService.getProductInfo(id);
return CzgResult.success(data);
}
/**
* 小程序点餐-商品SKU详情
*/
@GetMapping("/miniApp/sku/info")
@OperationLog("小程序点餐-商品SKU详情")
public CzgResult<ShopProductSkuInfoVo> getProductSkuInfo(ShopProductSkuParam param) {
ValidatorUtil.validateEntity(param, DefaultGroup.class);
ShopProductSkuInfoVo data = uProductService.getProductSkuInfo(param);
return CzgResult.success(data);
}
}

View File

@ -0,0 +1,31 @@
package com.czg.product.param;
import com.czg.validator.group.DefaultGroup;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 商品SKU查询参数
*
* @author tankaikai
* @since 2025-02-19 09:23
*/
@Data
public class ShopProductSkuParam implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 商品id
*/
@NotNull(message = "商品id不能为空", groups = DefaultGroup.class)
private Long id;
/**
* 选中的规格名称单规格传null,多规格如选择微辣+常温则传递微辣,常温顺序不能变
*/
private String specInfo;
}

View File

@ -2,9 +2,8 @@ package com.czg.product.service;
import com.czg.product.entity.Product;
import com.czg.product.param.MiniHomeProductParam;
import com.czg.product.vo.MiniAppHomeProductVo;
import com.czg.product.vo.ShopGroupProductVo;
import com.czg.product.vo.ShopProductVo;
import com.czg.product.param.ShopProductSkuParam;
import com.czg.product.vo.*;
import com.mybatisflex.core.service.IService;
import java.util.List;
@ -21,4 +20,8 @@ public interface UProductService extends IService<Product> {
List<ShopProductVo> queryHotsProductList();
List<ShopGroupProductVo> queryGroupProductList();
ShopProductInfoVo getProductInfo(Long id);
ShopProductSkuInfoVo getProductSkuInfo(ShopProductSkuParam param);
}

View File

@ -0,0 +1,115 @@
package com.czg.product.vo;
import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalTime;
/**
* 商品规格详情
*
* @author tankaikai
* @since 2025-02-19 09:23
*/
@Data
public class ShopProductInfoVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 商品id
*/
private Long id;
/**
* 商品名称
*/
private String name;
/**
* 短标题--促销语
*/
private String shortTitle;
/**
* 封面图url
*/
private String coverImg;
/**
* 商品图集
*/
private Object images;
/**
* 单位名称
*/
private String unitName;
/**
* 原价
*/
private BigDecimal originPrice;
/**
* 销售价
*/
private BigDecimal salePrice;
/**
* 会员价
*/
private BigDecimal memberPrice;
/**
* 是否售罄 1- 0-
*/
private Integer isSoldStock;
/**
* 库存数量
*/
private Integer stockNumber;
/**
* 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券
*/
private String type;
/**
* 套餐类型 0-固定套餐 1-可选套餐
*/
private String groupType;
/**
* 是否可售时间 1- 0-
*/
private Integer isSaleTime;
/**
* 起售数量
*/
private Integer suitNum;
/**
* 商品规格
*/
private Object selectSpecInfo;
/**
* 商品每周销售日 Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
*/
@JSONField(serialize = false)
private String days;
/**
* 可售卖起始时间
*/
@JSONField(serialize = false)
private LocalTime startTime;
/**
* 可售卖截止时间
*/
@JSONField(serialize = false)
private LocalTime endTime;
public Object getImages() {
return JSON.parseArray(Convert.toStr(images, "[]"));
}
/**
* {"口味":[{"甜度":["少甜","中甜","多甜"]},{"辣度":["微辣","重辣","变态辣"]},{"小料":["葱花","香菜","折耳根"]}]}
*/
public Object getSelectSpecInfo() {
return JSON.parseObject(Convert.toStr(selectSpecInfo, "{}"));
}
}

View File

@ -0,0 +1,77 @@
package com.czg.product.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 商品SKU详情
*
* @author tankaikai
* @since 2025-02-19 09:23
*/
@Data
public class ShopProductSkuInfoVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
private Long id;
/**
* 条形码
*/
private String barCode;
/**
* 商品Id
*/
private Long productId;
/**
* 原价
*/
private BigDecimal originPrice;
/**
* 成本价
*/
private BigDecimal costPrice;
/**
* 会员价
*/
private BigDecimal memberPrice;
/**
* 售价
*/
private BigDecimal salePrice;
/**
* 起售数量
*/
private Integer suitNum;
/**
* 规格详情
*/
private String specInfo;
/**
* 商品封面图
*/
private String coverImg;
/**
* 重量
*/
private BigDecimal weight;
/**
* 销量
*/
private BigDecimal realSalesNumber;
/**
* 是否售罄
*/
private Integer isPauseSale;
/**
* 商品库存
*/
private Integer stockNumber;
}

View File

@ -1,6 +1,7 @@
package com.czg.service.product.mapper;
import com.czg.product.entity.Product;
import com.czg.product.vo.ShopProductInfoVo;
import com.czg.product.vo.ShopProductVo;
import com.mybatisflex.core.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@ -20,4 +21,6 @@ public interface ProductMapper extends BaseMapper<Product> {
List<ShopProductVo> selectHotsProductList(@Param("shopId") Long shopId);
List<ShopProductVo> selectGroupProductList(@Param("shopId") Long shopId);
ShopProductInfoVo selectOneProductInfo(@Param("id") Long id, @Param("shopId") Long shopId);
}

View File

@ -6,13 +6,16 @@ import cn.hutool.core.util.StrUtil;
import com.czg.enums.DeleteEnum;
import com.czg.enums.StatusEnum;
import com.czg.enums.YesNoEnum;
import com.czg.exception.CzgException;
import com.czg.product.dto.ProdSkuDTO;
import com.czg.product.dto.ProductDTO;
import com.czg.product.entity.ProdGroup;
import com.czg.product.entity.ProdGroupRelation;
import com.czg.product.entity.ProdSku;
import com.czg.product.entity.Product;
import com.czg.product.enums.ProductTypeEnum;
import com.czg.product.param.MiniHomeProductParam;
import com.czg.product.param.ShopProductSkuParam;
import com.czg.product.service.UProductService;
import com.czg.product.vo.*;
import com.czg.sa.StpKit;
@ -197,6 +200,43 @@ public class UProductServiceImpl extends ServiceImpl<ProductMapper, Product> imp
return groupList.stream().filter(group -> CollUtil.isNotEmpty(group.getProductList())).toList();
}
@Override
public ShopProductInfoVo getProductInfo(Long id) {
Long shopId = StpKit.USER.getShopId(0L);
ShopProductInfoVo data = productMapper.selectOneProductInfo(id, shopId);
if (data == null) {
throw new CzgException("商品不可售");
}
return data;
}
@Override
public ShopProductSkuInfoVo getProductSkuInfo(ShopProductSkuParam param) {
Long shopId = StpKit.USER.getShopId(0L);
Product product = productMapper.selectOneById(param.getId());
if (product == null) {
throw new CzgException("商品信息不存在");
}
String specInfo = StrUtil.blankToDefault(param.getSpecInfo(), null);
ShopProductSkuInfoVo data = prodSkuMapper.selectOneByQueryAs(
query().eq(ProdSku::getProductId, param.getId())
.eq(ProdSku::getShopId, shopId)
.eq(ProdSku::getIsDel, DeleteEnum.NORMAL.value())
.eq(ProdSku::getIsGrounding, YesNoEnum.YES.value())
.eq(ProdSku::getSpecInfo, specInfo)
, ShopProductSkuInfoVo.class);
if (data == null) {
throw new CzgException("商品SKU不可售或不存在");
}
if (ProductTypeEnum.SINGLE.value().equals(product.getType())) {
data.setStockNumber(product.getStockNumber());
} else {
// TODO 临时数据后续对接库存系统
data.setStockNumber(1000);
}
return data;
}
/**
* 计算是否在可售时间内
*

View File

@ -5,10 +5,12 @@
<sql id="shopProductQuery">
select t1.id,
t1.name,
t1.short_title,
t2.origin_price,
t2.sale_price,
t2.member_price,
t1.cover_img,
t1.images,
t3.name as unit_name,
t1.is_sold_stock,
t1.stock_number,
@ -17,7 +19,8 @@
t1.days,
t1.start_time,
t1.end_time,
ifnull(t2.suit_num, 1) as suit_num
ifnull(t2.suit_num, 1) as suit_num,
t1.select_spec_info
from tb_product t1
left join (select x.product_id,
MIN(x.sale_price) as sale_price,
@ -53,4 +56,14 @@
</where>
order by t1.sort desc,t1.id desc
</select>
<select id="selectOneProductInfo" resultType="com.czg.product.vo.ShopProductInfoVo">
<include refid="shopProductQuery"/>
<where>
and t1.is_del = 0
and t1.is_sale = 1
and t2.sale_price is not null
and t1.shop_id = #{shopId}
and t1.id = #{id}
</where>
</select>
</mapper>