创建商品

This commit is contained in:
xuelijun
2025-07-30 10:45:19 +08:00
parent 4675e14813
commit 083b4e0bf1
19 changed files with 195 additions and 33 deletions

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
*
* https://www.mall4j.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.tashow.cloud.productapi.enums;
/**
* 商品规格参数、属性类型
* @author lgh
*/
public enum ProdPropRule {
// 规格属性 (用于商品商品发布时关联sku)
SPEC(1),
// 规格参数(用于商品搜索时,与分类关联搜索)
ATTRIBUTE(2);
private Integer num;
public Integer value() {
return num;
}
ProdPropRule(Integer num){
this.num = num;
}
public static ProdPropRule instance(Integer value) {
ProdPropRule[] enums = values();
for (ProdPropRule statusEnum : enums) {
if (statusEnum.value().equals(value)) {
return statusEnum;
}
}
return null;
}
}

View File

@@ -35,12 +35,12 @@ public class ProdController {
@PostMapping("/create")
@Operation(summary = "创建商品")
@PreAuthorize("@ss.hasPermission('tashow-module-product:prod:create')")
@PermitAll
public CommonResult<Long> createProd(@Valid @RequestBody ProdSaveReqVO createReqVO) {
return success(prodService.createProd(createReqVO));
}
@PutMapping("/update")
/* @PutMapping("/update")
@Operation(summary = "更新商品")
@PreAuthorize("@ss.hasPermission('tashow-module-product:prod:update')")
public CommonResult<Boolean> updateProd(@Valid @RequestBody ProdSaveReqVO updateReqVO) {
@@ -64,7 +64,7 @@ public class ProdController {
public CommonResult<ProdRespVO> getProd(@RequestParam("id") Long id) {
ProdDO prod = prodService.getProd(id);
return success(BeanUtils.toBean(prod, ProdRespVO.class));
}
}*/
@PermitAll
@GetMapping("/page")

View File

@@ -1,10 +1,15 @@
package com.tashow.cloud.product.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tashow.cloud.product.dto.ProdPropDO;
import com.tashow.cloud.product.dto.ProdPropValueDO;
import com.tashow.cloud.product.service.ProdPropService;
import com.tashow.cloud.product.service.ProdPropValueService;
import com.tashow.cloud.product.vo.prodprop.ProdPropPageReqVO;
import com.tashow.cloud.product.vo.prodprop.ProdPropRespVO;
import com.tashow.cloud.product.vo.prodprop.ProdPropSaveReqVO;
import com.tashow.cloud.productapi.enums.ProdPropRule;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@@ -38,15 +43,48 @@ public class ProdPropController {
@Resource
private ProdPropService prodPropService;
@Resource
private ProdPropValueService prodPropValueService;
@PostMapping("/create")
/* @PostMapping("/create")
@Operation(summary = "创建商品属性")
@PreAuthorize("@ss.hasPermission('tz:prod-prop:create')")
public CommonResult<Long> createProdProp(@Valid @RequestBody ProdPropSaveReqVO createReqVO) {
return success(prodPropService.createProdProp(createReqVO));
public CommonResult<Boolean> createProdProp(@Valid @RequestBody ProdPropSaveReqVO createReqVO) {
prodPropService.saveProdPropAndValues(createReqVO);
return success(true);
}*/
@GetMapping("/getProdPropList")
@Operation(summary = "获得商品属性列表")
public CommonResult<List<ProdPropDO>> getProdPropList(@Valid ProdPropRespVO pageReqVO) {
LambdaQueryWrapper<ProdPropDO> wrapper = new LambdaQueryWrapper<>();
// 处理规格名称模糊查询
if (StrUtil.isNotBlank(pageReqVO.getPropName())) {
wrapper.like(ProdPropDO::getPropName, pageReqVO.getPropName());
}
wrapper.eq(ProdPropDO::getRule, ProdPropRule.SPEC.value());
//TODO 获取当前登录用户
wrapper.eq(ProdPropDO::getShopId, 1L);
/*// 获取当前登录用户
Long userId = SecurityUtils.getUserId();
SysUser sysUser = sysUserService.selectUserById(userId);
if (sysUser.getShopId() != 100) {
wrapper.eq(ProdProp::getShopId, sysUser.getShopId());
}*/
List<ProdPropDO> list = prodPropService.list(wrapper);
list.forEach(prop -> {
List<ProdPropValueDO> values = prodPropValueService.list(
new LambdaQueryWrapper<ProdPropValueDO>()
.eq(ProdPropValueDO::getPropId, prop.getPropId())
);
prop.setProdPropValues(values);
});
return success(list);
}
@PutMapping("/update")
/* @PutMapping("/update")
@Operation(summary = "更新商品属性")
@PreAuthorize("@ss.hasPermission('tz:prod-prop:update')")
public CommonResult<Boolean> updateProdProp(@Valid @RequestBody ProdPropSaveReqVO updateReqVO) {
@@ -91,6 +129,6 @@ public class ProdPropController {
// 导出 Excel
ExcelUtils.write(response, "商品属性.xls", "数据", ProdPropRespVO.class,
BeanUtils.toBean(list, ProdPropRespVO.class));
}
}*/
}

View File

@@ -123,14 +123,6 @@ public class ProdDO extends BaseDO {
* 是否开启体重配置0关1开
*/
private Boolean weightSwitch;
/**
* 创建人
*/
private String createBy;
/**
* 修改人
*/
private String updateBy;
/**
* 版本 乐观锁
*/

View File

@@ -13,12 +13,11 @@ import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
@TableName("tz_prod_prop")
@KeySequence("tz_prod_prop_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProdPropDO extends BaseDO {
public class ProdPropDO{
/**
* 属性id
@@ -45,5 +44,9 @@ public class ProdPropDO extends BaseDO {
* 是否删除0否1是
*/
private Boolean isDelete;
/**
* 属性值
*/
@TableField(exist=false)
private List<ProdPropValueDO> prodPropValues;
}

View File

@@ -13,12 +13,11 @@ import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
@TableName("tz_prod_prop_value")
@KeySequence("tz_prod_prop_value_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProdPropValueDO extends BaseDO {
public class ProdPropValueDO {
/**
* 属性值ID

View File

@@ -23,12 +23,10 @@ public class ProdServiceAreaRelevanceDO extends BaseDO {
/**
* 关联的商品ID
*/
@TableId
private Long prodId;
/**
* 关联的服务区域ID
*/
@TableId
private Long areaId;
}

View File

@@ -24,12 +24,10 @@ public class ProdTagsDO extends BaseDO {
/**
* 商品id
*/
@TableId
private Long productId;
/**
* 标签id
*/
@TableId
private Long tagId;
}

View File

@@ -7,6 +7,7 @@ import com.tashow.cloud.mybatis.mybatis.core.query.LambdaQueryWrapperX;
import com.tashow.cloud.mybatis.mybatis.core.mapper.BaseMapperX;
import com.tashow.cloud.product.dto.ProdPropDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 商品属性 Mapper
@@ -16,5 +17,12 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ProdPropMapper extends BaseMapperX<ProdPropDO> {
/**
* 根据店铺id和属性名称获取商品属性
* @param propName
* @param shopId
* @param rule
* @return
*/
ProdPropDO getProdPropByPropNameAndShopId(@Param("propName") String propName, @Param("shopId") Long shopId, @Param("rule") Integer rule);
}

View File

@@ -7,6 +7,7 @@ import com.tashow.cloud.mybatis.mybatis.core.query.LambdaQueryWrapperX;
import com.tashow.cloud.mybatis.mybatis.core.mapper.BaseMapperX;
import com.tashow.cloud.product.dto.ProdPropValueDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 属性规则 Mapper
@@ -16,5 +17,11 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ProdPropValueMapper extends BaseMapperX<ProdPropValueDO> {
/**
* 插入商品属性数值
* @param propId
* @param prodPropValues
*/
void insertPropValues(@Param("propId") Long propId, @Param("prodPropValues") List<ProdPropValueDO> prodPropValues);
}

View File

@@ -2,6 +2,7 @@ package com.tashow.cloud.product.service;
import java.util.*;
import com.baomidou.mybatisplus.extension.service.IService;
import com.tashow.cloud.product.dto.ProdPropDO;
import com.tashow.cloud.product.vo.prodprop.ProdPropPageReqVO;
import com.tashow.cloud.product.vo.prodprop.ProdPropSaveReqVO;
@@ -14,7 +15,7 @@ import com.tashow.cloud.common.pojo.PageParam;
*
* @author 芋道源码
*/
public interface ProdPropService {
public interface ProdPropService extends IService<ProdPropDO> {
/**
* 创建商品属性
@@ -24,6 +25,7 @@ public interface ProdPropService {
*/
Long createProdProp(@Valid ProdPropSaveReqVO createReqVO);
void saveProdPropAndValues(ProdPropSaveReqVO createReqVO);
/**
* 更新商品属性
*

View File

@@ -2,6 +2,8 @@ package com.tashow.cloud.product.service;
import java.util.*;
import com.baomidou.mybatisplus.extension.service.IService;
import com.tashow.cloud.product.dto.ProdPropDO;
import com.tashow.cloud.product.dto.ProdPropValueDO;
import com.tashow.cloud.product.vo.prodpropvalue.ProdPropValuePageReqVO;
import com.tashow.cloud.product.vo.prodpropvalue.ProdPropValueSaveReqVO;
@@ -14,7 +16,7 @@ import com.tashow.cloud.common.pojo.PageParam;
*
* @author 芋道源码
*/
public interface ProdPropValueService {
public interface ProdPropValueService extends IService<ProdPropValueDO> {
/**
* 创建属性规则

View File

@@ -1,7 +1,10 @@
package com.tashow.cloud.product.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tashow.cloud.product.dto.ProdPropDO;
import com.tashow.cloud.product.mapper.ProdPropMapper;
import com.tashow.cloud.product.mapper.ProdPropValueMapper;
import com.tashow.cloud.product.service.ProdPropService;
import com.tashow.cloud.product.vo.prodprop.ProdPropPageReqVO;
import com.tashow.cloud.product.vo.prodprop.ProdPropSaveReqVO;
@@ -26,10 +29,12 @@ import static com.tashow.cloud.common.exception.util.ServiceExceptionUtil.except
*/
@Service
@Validated
public class ProdPropServiceImpl implements ProdPropService {
public class ProdPropServiceImpl extends ServiceImpl<ProdPropMapper, ProdPropDO> implements ProdPropService {
@Resource
private ProdPropMapper prodPropMapper;
@Resource
private ProdPropValueMapper prodPropValueMapper;
@Override
public Long createProdProp(ProdPropSaveReqVO createReqVO) {
@@ -40,6 +45,25 @@ public class ProdPropServiceImpl implements ProdPropService {
return prodProp.getPropId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveProdPropAndValues(ProdPropSaveReqVO createReqVO) {
if(createReqVO.getShopId()==null){
createReqVO.setShopId(1L);
}
ProdPropDO dbProdProp = prodPropMapper.getProdPropByPropNameAndShopId(createReqVO.getPropName(), createReqVO.getShopId(), createReqVO.getRule());
if (dbProdProp != null) {
throw new RuntimeException("已有相同名称规格");
}
ProdPropDO prodProp = BeanUtils.toBean(createReqVO, ProdPropDO.class);
prodPropMapper.insert(prodProp);
if (CollUtil.isEmpty(createReqVO.getProdPropValues())) {
return;
}
prodPropValueMapper.insertPropValues(prodProp.getPropId(), createReqVO.getProdPropValues());
}
@Override
public void updateProdProp(ProdPropSaveReqVO updateReqVO) {
// 校验存在

View File

@@ -1,6 +1,9 @@
package com.tashow.cloud.product.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tashow.cloud.product.dto.ProdPropDO;
import com.tashow.cloud.product.dto.ProdPropValueDO;
import com.tashow.cloud.product.mapper.ProdPropMapper;
import com.tashow.cloud.product.mapper.ProdPropValueMapper;
import com.tashow.cloud.product.service.ProdPropValueService;
import com.tashow.cloud.product.vo.prodpropvalue.ProdPropValuePageReqVO;
@@ -23,7 +26,7 @@ import static com.tashow.cloud.common.exception.util.ServiceExceptionUtil.except
*/
@Service
@Validated
public class ProdPropValueServiceImpl implements ProdPropValueService {
public class ProdPropValueServiceImpl extends ServiceImpl<ProdPropValueMapper, ProdPropValueDO> implements ProdPropValueService {
@Resource
private ProdPropValueMapper prodPropValueMapper;

View File

@@ -1,10 +1,14 @@
package com.tashow.cloud.product.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tashow.cloud.mybatis.mybatis.core.util.MyBatisUtils;
import com.tashow.cloud.product.dto.ProdDO;
import com.tashow.cloud.product.dto.SkuDO;
import com.tashow.cloud.product.mapper.ProdMapper;
import com.tashow.cloud.product.mapper.SkuMapper;
import com.tashow.cloud.product.service.ProdPropService;
import com.tashow.cloud.product.service.ProdService;
import com.tashow.cloud.product.vo.prod.ProdPageReqVO;
import com.tashow.cloud.product.vo.prod.ProdSaveReqVO;
@@ -33,12 +37,27 @@ public class ProdServiceImpl implements ProdService {
@Resource
private ProdMapper prodMapper;
@Resource
private SkuMapper skuMapper;
@Resource
private ProdPropService prodPropService;
@Override
public Long createProd(ProdSaveReqVO createReqVO) {
// 插入
ProdDO prod = BeanUtils.toBean(createReqVO, ProdDO.class);
prodMapper.insert(prod);
//保存sku
if (CollectionUtil.isNotEmpty(createReqVO.getSkuList())) {
List<SkuDO> skuList = createReqVO.getSkuList();
for(SkuDO sku : skuList){
sku.setProdId(prod.getProdId());
}
skuMapper.insert(skuList);
}
createReqVO.setProdId(prod.getProdId());
//保存规格
prodPropService.saveProdPropAndValues(createReqVO.getProdPropSaveReqVO());
// 返回
return prod.getProdId();
}

View File

@@ -1,9 +1,13 @@
package com.tashow.cloud.product.vo.prod;
import com.tashow.cloud.product.dto.SkuDO;
import com.tashow.cloud.product.vo.prodprop.ProdPropSaveReqVO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
@Schema(description = "管理后台 - 商品新增/修改 Request VO")
@Data
public class ProdSaveReqVO {
@@ -96,4 +100,10 @@ public class ProdSaveReqVO {
@Schema(description = "展示的权重")
private Integer top;
@Schema(description = "sku列表")
private List<SkuDO> skuList;
@Schema(description = "规格")
private ProdPropSaveReqVO prodPropSaveReqVO;
}

View File

@@ -1,5 +1,7 @@
package com.tashow.cloud.product.vo.prodprop;
import com.baomidou.mybatisplus.annotation.TableField;
import com.tashow.cloud.product.dto.ProdPropValueDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
@@ -21,10 +23,16 @@ public class ProdPropSaveReqVO {
@Schema(description = "店铺id", example = "2806")
private Long shopId;
@Schema(description = "商品id", example = "21671")
@Schema(description = "商品id(添加的时候不传)", example = "21671")
private Integer prodId;
@Schema(description = "是否删除0否1是")
private Boolean isDelete;
/**
* 属性值
*/
@TableField(exist=false)
@NotEmpty(message="规格属性值不能为空")
private List<ProdPropValueDO> prodPropValues;
}

View File

@@ -8,5 +8,7 @@
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
<select id="getProdPropByPropNameAndShopId" resultType="com.tashow.cloud.product.dto.ProdPropDO">
select * from tz_prod_prop where prop_name = #{propName} and shop_id = #{shopId} and rule = #{rule}
</select>
</mapper>

View File

@@ -8,5 +8,10 @@
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
<insert id="insertPropValues">
insert into tz_prod_prop_value (prop_id,prop_value) values
<foreach collection="prodPropValues" item="prodPropValue" separator=",">
(#{propId},#{prodPropValue.propValue})
</foreach>
</insert>
</mapper>