Merge remote-tracking branch 'origin/feature/1.8.0-uniapp' into ly_uniapp

# Conflicts:
#	yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApiImpl.java
#	yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java
#	yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java
#	yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java
#	yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java
#	yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
#	yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderItemConvert.java
#	yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
#	yudao-server/src/main/resources/application.yaml
This commit is contained in:
ex_yang.li@ca-nio.com
2022-09-15 17:09:17 +08:00
766 changed files with 52263 additions and 3877 deletions

View File

@@ -15,17 +15,18 @@
<name>${project.artifactId}</name>
<description>
商城大模块,由 product 商品、market 营销、trade 交易等组成
商城大模块,由 product 商品、market 营销、trade 交易 coupon等组成
</description>
<modules>
<module>yudao-module-coupon-api</module>
<module>yudao-module-coupon-biz</module>
<module>yudao-module-market-api</module>
<module>yudao-module-market-biz</module>
<module>yudao-module-product-api</module>
<module>yudao-module-product-biz</module>
<module>yudao-module-trade-api</module>
<module>yudao-module-trade-biz</module>
<module>yudao-module-coupon-api</module>
<module>yudao-module-coupon-biz</module>
</modules>
</project>

View File

@@ -23,6 +23,13 @@
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -14,7 +14,8 @@ import lombok.RequiredArgsConstructor;
@Getter
public enum CouponExpireTimeTypeEnum {
OPEN(1,"不开启"),CLOSE(0,"开启"),;
OPEN(1,"不开启"),
CLOSE(0,"开启"),;
/**
* 是否开启过期提醒

View File

@@ -14,7 +14,8 @@ import lombok.RequiredArgsConstructor;
@Getter
public enum CouponFetchTypeEnum {
LIMIT(0,""),NOT_LIMIT(0,"开启"),;
LIMIT(1,"限制"),
NOT_LIMIT(0,"不限制"),;
/**
* 是否开启过期提醒

View File

@@ -6,17 +6,16 @@ import lombok.RequiredArgsConstructor;
/**
* 优惠券 - 优惠类型
* 优惠券 - 优惠叠加类型
*
* @author Sin
*/
@RequiredArgsConstructor
@Getter
public enum CouponProductTypeEnum {
public enum CouponForbidPreferenceEnum {
PROCESSING(1,"进行中"),
END(2,"已结束"),
CLOSE(3,"已关闭"),;
UN_FORBID(0,"不限制"),
FORBID(1,"优惠券仅原价购买商品时可用");
/**
* 优惠券类型

View File

@@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.CouponTemplete.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* 优惠券 - 优惠券商品使用类型
*
* @author Sin
*/
@RequiredArgsConstructor
@Getter
public enum CouponGoodsTypeEnum {
ALL(1,"全部商品可用"),
POINT_PRODUCT(2,"指定商品可用"),
POINT_PRODUCT_NOT(3,"指定商品不可用"),;
/**
* 优惠券商品使用类型
*/
private final Integer type;
/**
* 优惠券商品使用类型名
*/
private final String name;
}

View File

@@ -6,7 +6,7 @@ import lombok.RequiredArgsConstructor;
/**
* 优惠券 - 优惠券类型
* 优惠券 - 优惠券状态类型
*
* @author Sin
*/
@@ -14,9 +14,9 @@ import lombok.RequiredArgsConstructor;
@Getter
public enum CouponStatusTypeEnum {
ALL(1,"全部商品可用"),
POINT_PRODUCT(2,"指定商品可用"),
POINT_PRODUCT_NOT(3,"指定商品不可用不能为空"),;
PROCESSING(1,"进行中"),
END(2,"已结束"),
CLOSE(3,"已关闭"),;
/**
* 优惠券类型

View File

@@ -6,7 +6,7 @@ import lombok.RequiredArgsConstructor;
/**
* 优惠券 - 优惠券类型
* 优惠券使用类型 - 优惠券使用类型类型
*
* @author Sin
*/
@@ -18,11 +18,11 @@ public enum CouponUseLimitEnum {
NO_LIMIT(2,"有门槛"),;
/**
* 优惠券类型
* 优惠券使用类型
*/
private final Integer type;
/**
* 优惠券类型名
* 优惠券使用类型名
*/
private final String name;

View File

@@ -14,7 +14,7 @@ public enum CouponValidityTypeEnum {
TIME_RANGE_EXPIRTED(1,"时间范围过期"),
EXPIRES_AFTER_FIXED_DATE(2,"领取之日固定日期后过期"),
EXPIRES_DATE_NEXT_FIEXD_DATE(3,"领取次日固定日期后过期不能为空"),;
EXPIRES_DATE_NEXT_FIEXD_DATE(3,"领取次日固定日期后过期"),;
/**

View File

@@ -3,19 +3,18 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yudao-module-mall</artifactId>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-mall</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-coupon-biz</artifactId>
<packaging>jar</packaging>
<artifactId>yudao-module-coupon-biz</artifactId>
<name>${project.artifactId}</name>
<description>
trade 模块,主要实现交易相关功能
例如:订单、退款、购物车等功能。
coupon模块主要负责优惠券的一些业务含发布优惠券模板分发优惠券等
</description>
<dependencies>

View File

@@ -21,7 +21,7 @@ import cn.iocoder.yudao.module.coupon.service.coupon.CouponService;
@Api(tags = "管理后台 - 优惠券")
@RestController
@RequestMapping("/coupon/coupon/")
@RequestMapping("/coupon/item")
@Validated
public class CouponController {
@@ -69,7 +69,7 @@ public class CouponController {
@GetMapping("/list")
@ApiOperation("获得优惠券列表")
// @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('coupon::query')")
public CommonResult<List<CouponRespVO>> getList(@RequestParam("ids") Collection<Long> ids) {
List<CouponDO> list = couponService.getList(ids);

View File

@@ -68,7 +68,7 @@ public class CouponBaseVO {
private Boolean whetherForbidPreference;
@ApiModelProperty(value = "是否开启过期提醒0-不开启 1-开启", required = true)
@NotNull(message = "是否开启过期提醒0-不开启 1-开启不能为空")
@NotNull(message = "是否开启过期提醒0-不开启 1-开启")
private Boolean whetherExpireNotice;
@ApiModelProperty(value = "过期前N天提醒", required = true)

View File

@@ -1,81 +0,0 @@
package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete;
import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.*;
import cn.iocoder.yudao.module.coupon.convert.CouponTemplete.CouponTempleteConvert;
import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
import cn.iocoder.yudao.module.coupon.service.CouponTemplete.CouponTempleteService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.*;
import javax.validation.*;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Api(tags = "管理后台 - 优惠券模板")
@RestController
@RequestMapping("/coupon/CouponTemplete/")
@Validated
public class CouponTempleteController {
@Resource
private CouponTempleteService Service;
@PostMapping("/create")
@ApiOperation("创建优惠券模板")
@PreAuthorize("@ss.hasPermission('CouponTemplete::create')")
public CommonResult<Long> create(@Valid @RequestBody CouponTempleteCreateReqVO createReqVO) {
return success(Service.create(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新优惠券模板")
@PreAuthorize("@ss.hasPermission('CouponTemplete::update')")
public CommonResult<Boolean> update(@Valid @RequestBody CouponTempleteUpdateReqVO updateReqVO) {
Service.update(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除优惠券模板")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('CouponTemplete::delete')")
public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
Service.delete(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得优惠券模板")
// @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('CouponTemplete::query')")
public CommonResult<CouponTempleteRespVO> get(@RequestParam("id") Long id) {
CouponTempleteDO couponTempleteDO = Service.get(id);
return success(CouponTempleteConvert.INSTANCE.convert(couponTempleteDO));
}
@GetMapping("/list")
@ApiOperation("获得优惠券模板列表")
// @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('CouponTemplete::query')")
public CommonResult<List<CouponTempleteRespVO>> getList(@RequestParam("ids") Collection<Long> ids) {
List<CouponTempleteDO> list = Service.getList(ids);
return success(CouponTempleteConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@ApiOperation("获得优惠券模板分页")
@PreAuthorize("@ss.hasPermission('CouponTemplete::query')")
public CommonResult<PageResult<CouponTempleteRespVO>> getPage(@Valid CouponTempletePageReqVO pageVO) {
PageResult<CouponTempleteDO> pageResult = Service.getPage(pageVO);
return success(CouponTempleteConvert.INSTANCE.convertPage(pageResult));
}
}

View File

@@ -0,0 +1,81 @@
package cn.iocoder.yudao.module.coupon.controller.admin.templete;
import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.*;
import cn.iocoder.yudao.module.coupon.convert.CouponTemplete.CouponTempleteConvert;
import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
import cn.iocoder.yudao.module.coupon.service.CouponTemplete.CouponTempleteService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.*;
import javax.validation.*;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Api(tags = "管理后台 - 优惠券模板")
@RestController
@RequestMapping("/coupon/template")
@Validated
public class CouponTempleteController {
@Resource
private CouponTempleteService couponTempleteServiceService;
@PostMapping("/create")
@ApiOperation("创建优惠券模板")
@PreAuthorize("@ss.hasPermission('CouponTemplete::create')")
public CommonResult<Long> create(@Valid @RequestBody CouponTempleteCreateReqVO createReqVO) {
return success(couponTempleteServiceService.create(createReqVO));
}
// @PutMapping("/update")
// @ApiOperation("更新优惠券模板")
// @PreAuthorize("@ss.hasPermission('CouponTemplete::update')")
// public CommonResult<Boolean> update(@Valid @RequestBody CouponTempleteUpdateReqVO updateReqVO) {
// couponTempleteServiceService.update(updateReqVO);
// return success(true);
// }
//
// @DeleteMapping("/delete")
// @ApiOperation("删除优惠券模板")
// @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
// @PreAuthorize("@ss.hasPermission('CouponTemplete::delete')")
// public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
// couponTempleteServiceService.delete(id);
// return success(true);
// }
//
// @GetMapping("/get")
// @ApiOperation("获得优惠券模板")
// @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
// @PreAuthorize("@ss.hasPermission('CouponTemplete::query')")
// public CommonResult<CouponTempleteRespVO> get(@RequestParam("id") Long id) {
// CouponTempleteDO couponTempleteDO = couponTempleteServiceService.get(id);
// return success(CouponTempleteConvert.INSTANCE.convert(couponTempleteDO));
// }
//
// @GetMapping("/list")
// @ApiOperation("获得优惠券模板列表")
// @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
// @PreAuthorize("@ss.hasPermission('CouponTemplete::query')")
// public CommonResult<List<CouponTempleteRespVO>> getList(@RequestParam("ids") Collection<Long> ids) {
// List<CouponTempleteDO> list = couponTempleteServiceService.getList(ids);
// return success(CouponTempleteConvert.INSTANCE.convertList(list));
// }
//
@GetMapping("/page")
@ApiOperation("获得优惠券模板分页")
@PreAuthorize("@ss.hasPermission('CouponTemplete::query')")
public CommonResult<PageResult<CouponTempleteRespVO>> getPage(@Valid CouponTempletePageReqVO pageVO) {
PageResult<CouponTempleteDO> pageResult = couponTempleteServiceService.getPage(pageVO);
return success(CouponTempleteConvert.INSTANCE.convertPage(pageResult));
}
}

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo;
package cn.iocoder.yudao.module.coupon.controller.admin.templete.vo;
import lombok.*;
import java.util.*;
@@ -34,7 +34,7 @@ public class CouponTempleteBaseVO {
@ApiModelProperty(value = "适用商品类型1-全部商品可用2-指定商品可用3-指定商品不可用", required = true)
@NotNull(message = "适用商品类型1-全部商品可用2-指定商品可用3-指定商品不可用不能为空")
private Boolean goodsType;
private Integer goodsType;
@ApiModelProperty(value = "适用商品id")
private String productIds;
@@ -104,7 +104,7 @@ public class CouponTempleteBaseVO {
@ApiModelProperty(value = "领取是否无限制0-否 1是", required = true)
@NotNull(message = "是否无限制0-否 1是 不能为空")
@NotNull(message = "是否无限制0-否 1是")
private Boolean whetherLimitless;
@ApiModelProperty(value = "每人最大领取个数", required = true)

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo;
package cn.iocoder.yudao.module.coupon.controller.admin.templete.vo;
import lombok.*;
import io.swagger.annotations.*;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo;
package cn.iocoder.yudao.module.coupon.controller.admin.templete.vo;
import lombok.*;
import java.util.*;
@@ -39,7 +39,7 @@ public class CouponTempleteExcelVO {
private Integer usedCount;
@ExcelProperty("适用商品类型1-全部商品可用2-指定商品可用3-指定商品不可用")
private Boolean goodsType;
private Integer goodsType;
@ExcelProperty("适用商品id")
private String productIds;
@@ -66,7 +66,7 @@ public class CouponTempleteExcelVO {
private BigDecimal maxMoney;
@ExcelProperty("过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期")
private Boolean validityType;
private Integer validityType;
@ExcelProperty("使用开始日期 过期类型1时必填")
private Date startUseTime;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo;
package cn.iocoder.yudao.module.coupon.controller.admin.templete.vo;
import lombok.*;
import java.util.*;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo;
package cn.iocoder.yudao.module.coupon.controller.admin.templete.vo;
import lombok.*;
import io.swagger.annotations.*;

View File

@@ -4,10 +4,10 @@ import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteCreateReqVO;
import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteExcelVO;
import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteRespVO;
import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteUpdateReqVO;
import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteCreateReqVO;
import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteExcelVO;
import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteRespVO;
import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteUpdateReqVO;
import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

View File

@@ -57,7 +57,7 @@ public class CouponTempleteDO extends BaseDO {
/**
* 适用商品类型1-全部商品可用2-指定商品可用3-指定商品不可用
*/
private Boolean goodsType;
private Integer goodsType;
/**
* 适用商品id
*/
@@ -93,7 +93,7 @@ public class CouponTempleteDO extends BaseDO {
/**
* 过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期
*/
private Boolean validityType;
private Integer validityType;
/**
* 使用开始日期 过期类型1时必填
*/

View File

@@ -5,8 +5,8 @@ import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteExportReqVO;
import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempletePageReqVO;
import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteExportReqVO;
import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempletePageReqVO;
import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
import org.apache.ibatis.annotations.Mapper;

View File

@@ -0,0 +1,6 @@
/**
* coupon模块主要负责麦一些优惠券的额增删
*
* 1. Controller URL以 /coumon/ 开头,避免和其它 Module 冲突
*/
package cn.iocoder.yudao.module.coupon;

View File

@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.coupon.service.CouponTemplete;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.*;
import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;

View File

@@ -2,14 +2,13 @@ package cn.iocoder.yudao.module.coupon.service.CouponTemplete;
import cn.iocoder.yudao.module.CouponTemplete.enums.CouponTypeEnum;
import cn.iocoder.yudao.module.CouponTemplete.enums.CouponValidityTypeEnum;
import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteCreateReqVO;
import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteExportReqVO;
import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempletePageReqVO;
import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteUpdateReqVO;
import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteCreateReqVO;
import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteExportReqVO;
import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempletePageReqVO;
import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteUpdateReqVO;
import cn.iocoder.yudao.module.coupon.convert.CouponTemplete.CouponTempleteConvert;
import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
import cn.iocoder.yudao.module.coupon.dal.mysql.CouponTemplete.CouponTempleteMapper;
import cn.iocoder.yudao.module.coupon.service.CouponTemplete.CouponTempleteService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@@ -41,7 +40,7 @@ public class CouponTempleteServiceImpl implements CouponTempleteService {
/* 验证类型、判断必填*/
checkCouponType(createReqVO);
/*todo 验证过期类型、判断必填*/
/*验证过期类型、判断必填*/
checkValidityType(createReqVO);

View File

@@ -19,15 +19,10 @@ public class PriceCalculateRespDTO {
*/
private Order order;
/**
* 商品 SKU 数组
*/
private List<Item> items;
/**
* 营销活动数组
*
* 只对应 {@link #items} 商品匹配的活动
* 只对应 {@link Order#items} 商品匹配的活动
*/
private List<Promotion> promotions;
@@ -40,13 +35,13 @@ public class PriceCalculateRespDTO {
/**
* 商品原价(总),单位:分
*
* 基于 {@link Item#getTotalOriginalPrice()} 求和
* 基于 {@link OrderItem#getTotalOriginalPrice()} 求和
*/
private Integer skuOriginalPrice;
/**
* 商品优惠(总),单位:分
*
* 基于 {@link Item#getTotalPromotionPrice()} 求和
* 基于 {@link OrderItem#getTotalPromotionPrice()} 求和
*/
private Integer skuPromotionPrice;
/**
@@ -69,6 +64,10 @@ public class PriceCalculateRespDTO {
*/
// * - {@link #couponPrice} // TODO 芋艿:靠营销表记录
private Integer payPrice;
/**
* 商品 SKU 数组
*/
private List<OrderItem> items;
// ========== 营销基本信息 ==========
/**
@@ -85,10 +84,15 @@ public class PriceCalculateRespDTO {
}
/**
* 商品 SKU
* 订单商品 SKU
*/
@Data
public static class Item extends PriceCalculateReqDTO.Item {
public static class OrderItem extends PriceCalculateReqDTO.Item {
/**
* 购买数量
*/
private Integer count;
/**
* 商品原价(单),单位:分
@@ -140,6 +144,10 @@ public class PriceCalculateRespDTO {
* 例如说:营销活动的编号、优惠劵的编号
*/
private Long id;
/**
* 营销名字
*/
private String name;
/**
* 营销类型
*
@@ -152,10 +160,6 @@ public class PriceCalculateRespDTO {
* 枚举 {@link PromotionLevelEnum}
*/
private Integer level;
/**
* 匹配的商品 SKU 数组
*/
private List<Item> items;
/**
* 计算时的原价(总),单位:分
*/
@@ -164,6 +168,13 @@ public class PriceCalculateRespDTO {
* 计算时的优惠(总),单位:分
*/
private Integer totalPromotionPrice;
/**
* 匹配的商品 SKU 数组
*/
private List<PromotionItem> items;
// ========== 匹配情况 ==========
/**
* 是否满足优惠条件
*/
@@ -176,26 +187,26 @@ public class PriceCalculateRespDTO {
*/
private String meetTip;
}
/**
* 营销匹配的商品 SKU
*/
@Data
public static class PromotionItem {
/**
* 匹配的商品 SKU
* 商品 SKU 编号
*/
@Data
public static class Item {
/**
* 商品 SKU 编号
*/
private Long skuId;
/**
* 计算时的原价(总),单位:分
*/
private Integer totalOriginalPrice;
/**
* 计算时的优惠(总),单位:分
*/
private Integer totalPromotionPrice;
}
private Long skuId;
/**
* 计算时的原价(总),单位:分
*/
private Integer totalOriginalPrice;
/**
* 计算时的优惠(总),单位:分
*/
private Integer totalPromotionPrice;
}

View File

@@ -24,6 +24,11 @@
<artifactId>yudao-module-market-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-product-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>

View File

@@ -0,0 +1 @@
package cn.iocoder.yudao.module.market.api.discount;

View File

@@ -2,19 +2,25 @@ package cn.iocoder.yudao.module.market.api.price;
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO;
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
import cn.iocoder.yudao.module.market.service.price.PriceService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
/**
* @author LeeYan9
* @since 2022-09-06
* 价格 API 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class PriceApiImpl implements PriceApi {
@Resource
private PriceService priceService;
@Override
public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) {
return null;
return priceService.calculatePrice(calculateReqDTO);
}
}

View File

@@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.market.convert.price;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO;
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Mapper
public interface PriceConvert {
PriceConvert INSTANCE = Mappers.getMapper(PriceConvert.class);
default PriceCalculateRespDTO convert(PriceCalculateReqDTO calculateReqDTO, List<ProductSkuRespDTO> skuList) {
// 创建 PriceCalculateRespDTO 对象
PriceCalculateRespDTO priceCalculate = new PriceCalculateRespDTO();
priceCalculate.setOrder(new PriceCalculateRespDTO.Order().setSkuOriginalPrice(0).setSkuPromotionPrice(0)
.setOrderPromotionPrice(0).setDeliveryPrice(0).setPayPrice(0).setItems(new ArrayList<>())
.setCouponId(calculateReqDTO.getCouponId()));
priceCalculate.setPromotions(new ArrayList<>());
// 创建它的 OrderItem 属性
Map<Long, Integer> skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(),
PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount);
skuList.forEach(sku -> {
Integer count = skuIdCountMap.get(sku.getId());
PriceCalculateRespDTO.OrderItem orderItem = new PriceCalculateRespDTO.OrderItem().setCount(count)
.setOriginalPrice(sku.getPrice()).setTotalOriginalPrice(sku.getPrice() * count).setTotalPromotionPrice(0);
orderItem.setTotalPresentPrice(orderItem.getTotalPresentPrice()).setPresentPrice(orderItem.getOriginalPrice())
.setTotalPayPrice(orderItem.getTotalPayPrice());
priceCalculate.getOrder().getItems().add(orderItem);
});
return priceCalculate;
}
}

View File

@@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.market.service.price;
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO;
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
/**
* 价格计算 Service 接口
*
* @author 芋道源码
*/
public interface PriceService {
/**
* 计算商品的价格
*
* @param calculateReqDTO 价格请求
* @return 价格相应
*/
PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO);
}

View File

@@ -0,0 +1,64 @@
package cn.iocoder.yudao.module.market.service.price;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO;
import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
import cn.iocoder.yudao.module.market.convert.price.PriceConvert;
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH;
/**
* 价格计算 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class PriceServiceImpl implements PriceService {
@Resource
private ProductSkuApi productSkuApi;
@Override
public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) {
// 获得商品 SKU 数组
List<ProductSkuRespDTO> skuList = checkProductSkus(calculateReqDTO);
// 初始化 PriceCalculateRespDTO 对象
PriceCalculateRespDTO priceCalculate = PriceConvert.INSTANCE.convert(calculateReqDTO, skuList);
// 计算【限时折扣】促销 TODO 待实现
// 计算【满减送】促销 TODO 待实现
// 计算【优惠劵】促销 TODO 待实现
return priceCalculate;
}
private List<ProductSkuRespDTO> checkProductSkus(PriceCalculateReqDTO calculateReqDTO) {
// 获得商品 SKU 数组
Map<Long, Integer> skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(),
PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount);
List<ProductSkuRespDTO> skus = productSkuApi.getSkuList(skuIdCountMap.keySet());
// 校验商品 SKU
skus.forEach(sku -> {
Integer count = skuIdCountMap.get(sku.getId());
if (count == null) {
throw exception(SKU_NOT_EXISTS);
}
if (count > sku.getStock()) {
throw exception(SKU_STOCK_NOT_ENOUGH);
}
});
return skus;
}
}

View File

@@ -1,25 +1,34 @@
package cn.iocoder.yudao.module.product.api.sku;
import cn.iocoder.yudao.module.product.api.sku.dto.SkuDecrementStockBatchReqDTO;
import cn.iocoder.yudao.module.product.api.sku.dto.SkuInfoRespDTO;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import java.util.Collection;
import java.util.List;
/**
* 商品 SKU API 接口
*
* @author LeeYan9
* @since 2022-08-26
*/
public interface ProductSkuApi {
/**
* 查询 SKU 信息
*
* @param id SKU 编号
* @return SKU 信息
*/
ProductSkuRespDTO getSku(Long id);
/**
* 根据skuId列表 查询sku信息
* 批量查询 SKU 数组
*
* @param skuIds sku ID列表
* @return sku信息列表
* @param ids SKU 编号列表
* @return SKU 数组
*/
List<SkuInfoRespDTO> getSkusByIds(Collection<Long> skuIds);
List<ProductSkuRespDTO> getSkuList(Collection<Long> ids);
/**
* 批量扣减sku库存
@@ -27,4 +36,5 @@ public interface ProductSkuApi {
* @param batchReqDTO sku库存信息列表
*/
void decrementStockBatch(SkuDecrementStockBatchReqDTO batchReqDTO);
}

View File

@@ -6,11 +6,13 @@ import lombok.Data;
import java.util.List;
/**
* 商品 SKU 信息 Response DTO
*
* @author LeeYan9
* @since 2022-08-26
*/
@Data
public class SkuInfoRespDTO {
public class ProductSkuRespDTO {
/**
* 商品 SKU 编号自增

View File

@@ -6,17 +6,19 @@ import java.util.Collection;
import java.util.List;
/**
* 商品 SPU API 接口
*
* @author LeeYan9
* @since 2022-08-26
*/
public interface ProductSpuApi {
/**
* 根据spuId列表 查询spu信息
* 批量查询 SPU 数组
*
* @param spuIds spu ID列表
* @return spu信息列表
* @param ids SPU 编号列表
* @return SPU 数组
*/
List<SpuInfoRespDTO> getSpusByIds(Collection<Long> spuIds);
List<SpuInfoRespDTO> getSpuList(Collection<Long> ids);
}

View File

@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.product.api.spu.dto;
import cn.iocoder.yudao.module.product.api.sku.dto.SkuInfoRespDTO;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import lombok.Data;
@@ -80,25 +80,25 @@ public class SpuInfoRespDTO {
/**
* 最小价格,单位使用:分
* <p>
* 基于其对应的 {@link SkuInfoRespDTO#getPrice()} 最小值
* 基于其对应的 {@link ProductSkuRespDTO#getPrice()} 最小值
*/
private Integer minPrice;
/**
* 最大价格,单位使用:分
* <p>
* 基于其对应的 {@link SkuInfoRespDTO#getPrice()} 最大值
* 基于其对应的 {@link ProductSkuRespDTO#getPrice()} 最大值
*/
private Integer maxPrice;
/**
* 市场价,单位使用:分
* <p>
* 基于其对应的 {@link SkuInfoRespDTO#getMarketPrice()} 最大值
* 基于其对应的 {@link ProductSkuRespDTO#getMarketPrice()} 最大值
*/
private Integer marketPrice;
/**
* 总库存
* <p>
* 基于其对应的 {@link SkuInfoRespDTO#getStock()} 求和
* 基于其对应的 {@link ProductSkuRespDTO#getStock()} 求和
*/
private Integer totalStock;
/**

View File

@@ -10,30 +10,32 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
public interface ErrorCodeConstants {
// ========== 商品分类相关 1008001000 ============
ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在");
ErrorCode PRODUCT_CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1008001001, "父分类不存在");
ErrorCode PRODUCT_CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类");
ErrorCode PRODUCT_CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除");
ErrorCode PRODUCT_CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用");
ErrorCode PRODUCT_CATEGORY_LEVEL = new ErrorCode(1008001005, "商品需挂在三级分类下");
ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在");
ErrorCode CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1008001001, "父分类不存在");
ErrorCode CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类");
ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除");
ErrorCode CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用");
ErrorCode CATEGORY_LEVEL_ERROR = new ErrorCode(1008001005, "商品分类不正确,原因:必须使用第三级的商品分类下");
// ========== 品牌相关编号 1008002000 ==========
ErrorCode PRODUCT_BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在");
// ========== 商品品牌相关编号 1008002000 ==========
ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在");
ErrorCode BRAND_DISABLED = new ErrorCode(1008002001, "品牌不存在");
ErrorCode BRAND_NAME_EXISTS = new ErrorCode(1008002002, "品牌名称已存在");
// ========== 规格名称 1008003000 ==========
// ========== 商品规格名称 1008003000 ==========
ErrorCode PROPERTY_NOT_EXISTS = new ErrorCode(1008003000, "规格名称不存在");
// ========== 规格值 1008004000 ==========
ErrorCode PROPERTY_VALUE_NOT_EXISTS = new ErrorCode(1008004000, "规格值不存在");
// ========== 商品spu 1008005000 ==========
ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品spu不存在");
// ========== 商品 SPU 1008005000 ==========
ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在");
// ========== 商品sku 1008006000 ==========
ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品sku不存在");
ErrorCode SKU_PROPERTIES_DUPLICATED = new ErrorCode(1008006001, "商品sku的属性组合存在重复");
// ========== 商品 SKU 1008006000 ==========
ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品 SKU 不存在");
ErrorCode SKU_PROPERTIES_DUPLICATED = new ErrorCode(1008006001, "商品 SKU 的属性组合存在重复");
ErrorCode SPU_ATTR_NUMBERS_MUST_BE_EQUALS = new ErrorCode(1008006002, "一个 SPU 下的每个 SKU其规格数必须一致");
ErrorCode SPU_SKU_NOT_DUPLICATE = new ErrorCode(1008006003, "一个 SPU 下的每个 SKU必须不重复");
ErrorCode SKU_STOCK_NOT_ENOUGH = new ErrorCode(1008006004, "商品 SKU 库存不足");
ErrorCode PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS = new ErrorCode(1008006002, "一个 Spu 下的每个 SKU ,其规格数必须一致");
ErrorCode PRODUCT_SPU_SKU_NOT_DUPLICATE = new ErrorCode(1008006003, "一个 SPU 下的每个 SKU ,必须不重复");
}

View File

@@ -0,0 +1 @@
package cn.iocoder.yudao.module.product.api;

View File

@@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.product.controller.admin.brand;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*;
import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
@@ -16,13 +14,11 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Comparator;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "管理后台 - 商品品牌")
@RestController
@@ -37,7 +33,7 @@ public class ProductBrandController {
@ApiOperation("创建品牌")
@PreAuthorize("@ss.hasPermission('product:brand:create')")
public CommonResult<Long> createBrand(@Valid @RequestBody ProductBrandCreateReqVO createReqVO) {
return success(brandService.createProductBrand(createReqVO));
return success(brandService.createBrand(createReqVO));
}
@PutMapping("/update")
@@ -74,4 +70,13 @@ public class ProductBrandController {
return success(ProductBrandConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/list")
@ApiOperation("获得品牌列表")
@PreAuthorize("@ss.hasPermission('product:brand:query')")
public CommonResult<List<ProductBrandRespVO>> getBrandList(@Valid ProductBrandListReqVO listVO) {
List<ProductBrandDO> list = brandService.getBrandList(listVO);
list.sort(Comparator.comparing(ProductBrandDO::getSort));
return success(ProductBrandConvert.INSTANCE.convertList(list));
}
}

View File

@@ -20,7 +20,8 @@ public class ProductBrandBaseVO {
@NotNull(message = "品牌图片不能为空")
private String picUrl;
@ApiModelProperty(value = "品牌排序", example = "1")
@ApiModelProperty(value = "品牌排序", required = true, example = "1")
@NotNull(message = "品牌排序不能为空")
private Integer sort;
@ApiModelProperty(value = "品牌描述", example = "描述")

View File

@@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel(value = "管理后台 - 商品品牌分页 Request VO")
@Data
public class ProductBrandListReqVO {
@ApiModelProperty(value = "品牌名称", example = "芋道")
private String name;
}

View File

@@ -21,7 +21,7 @@ public class ProductBrandPageReqVO extends PageParam {
@ApiModelProperty(value = "品牌名称", example = "芋道")
private String name;
@ApiModelProperty(value = "状态", example = "0")
@ApiModelProperty(value = "状态", example = "0", notes = "参考 CommonStatusEnum 枚举")
private Integer status;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)

View File

@@ -34,15 +34,15 @@ public class ProductCategoryController {
@PostMapping("/create")
@ApiOperation("创建商品分类")
@PreAuthorize("@ss.hasPermission('product:category:create')")
public CommonResult<Long> createProductCategory(@Valid @RequestBody ProductCategoryCreateReqVO createReqVO) {
return success(categoryService.createProductCategory(createReqVO));
public CommonResult<Long> createCategory(@Valid @RequestBody ProductCategoryCreateReqVO createReqVO) {
return success(categoryService.createCategory(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新商品分类")
@PreAuthorize("@ss.hasPermission('product:category:update')")
public CommonResult<Boolean> updateProductCategory(@Valid @RequestBody ProductCategoryUpdateReqVO updateReqVO) {
categoryService.updateProductCategory(updateReqVO);
public CommonResult<Boolean> updateCategory(@Valid @RequestBody ProductCategoryUpdateReqVO updateReqVO) {
categoryService.updateCategory(updateReqVO);
return success(true);
}
@@ -50,8 +50,8 @@ public class ProductCategoryController {
@ApiOperation("删除商品分类")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('product:category:delete')")
public CommonResult<Boolean> deleteProductCategory(@RequestParam("id") Long id) {
categoryService.deleteProductCategory(id);
public CommonResult<Boolean> deleteCategory(@RequestParam("id") Long id) {
categoryService.deleteCategory(id);
return success(true);
}
@@ -59,16 +59,16 @@ public class ProductCategoryController {
@ApiOperation("获得商品分类")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('product:category:query')")
public CommonResult<ProductCategoryRespVO> getProductCategory(@RequestParam("id") Long id) {
ProductCategoryDO category = categoryService.getProductCategory(id);
public CommonResult<ProductCategoryRespVO> getCategory(@RequestParam("id") Long id) {
ProductCategoryDO category = categoryService.getCategory(id);
return success(ProductCategoryConvert.INSTANCE.convert(category));
}
@GetMapping("/list")
@ApiOperation("获得商品分类列表")
@PreAuthorize("@ss.hasPermission('product:category:query')")
public CommonResult<List<ProductCategoryRespVO>> getProductCategoryList(@Valid ProductCategoryListReqVO treeListReqVO) {
List<ProductCategoryDO> list = categoryService.getEnableProductCategoryList(treeListReqVO);
public CommonResult<List<ProductCategoryRespVO>> getCategoryList(@Valid ProductCategoryListReqVO treeListReqVO) {
List<ProductCategoryDO> list = categoryService.getEnableCategoryList(treeListReqVO);
list.sort(Comparator.comparing(ProductCategoryDO::getSort));
return success(ProductCategoryConvert.INSTANCE.convertList(list));
}

View File

@@ -1,29 +1,22 @@
package cn.iocoder.yudao.module.product.controller.admin.property;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.*;
import cn.iocoder.yudao.module.product.convert.property.ProductPropertyConvert;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*;
import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Api(tags = "管理后台 - 规格名称")
@RestController
@@ -68,30 +61,23 @@ public class ProductPropertyController {
@GetMapping("/list")
@ApiOperation("获得规格名称列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('product:property:query')")
public CommonResult<List<ProductPropertyRespVO>> getPropertyList(@RequestParam("ids") Collection<Long> ids) {
List<ProductPropertyDO> list = productPropertyService.getPropertyList(ids);
return success(ProductPropertyConvert.INSTANCE.convertList(list));
public CommonResult<List<ProductPropertyRespVO>> getPropertyList(@Valid ProductPropertyListReqVO listReqVO) {
return success(productPropertyService.getPropertyList(listReqVO));
}
@GetMapping("/page")
@ApiOperation("获得规格名称分页")
@PreAuthorize("@ss.hasPermission('product:property:query')")
public CommonResult<PageResult<ProductPropertyRespVO>> getPropertyPage(@Valid ProductPropertyPageReqVO pageVO) {
return success(productPropertyService.getPropertyListPage(pageVO));
return success(productPropertyService.getPropertyPage(pageVO));
}
@GetMapping("/export-excel")
@ApiOperation("导出规格名称 Excel")
@PreAuthorize("@ss.hasPermission('product:property:export')")
@OperateLog(type = EXPORT)
public void exportPropertyExcel(@Valid ProductPropertyExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<ProductPropertyDO> list = productPropertyService.getPropertyList(exportReqVO);
// 导出 Excel
List<ProductPropertyExcelVO> datas = ProductPropertyConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "规格名称.xls", "数据", ProductPropertyExcelVO.class, datas);
@GetMapping("/listAndValue")
@ApiOperation("获得规格名称列表")
@PreAuthorize("@ss.hasPermission('product:property:query')")
public CommonResult<List<ProductPropertyAndValueRespVO>> getPropertyAndValueList(@Valid ProductPropertyListReqVO listReqVO) {
return success(productPropertyService.getPropertyAndValueList(listReqVO));
}
}

View File

@@ -0,0 +1,70 @@
package cn.iocoder.yudao.module.product.controller.admin.property;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO;
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Api(tags = "管理后台 - 规格值名称")
@RestController
@RequestMapping("/product/property/value")
@Validated
public class ProductPropertyValueController {
@Resource
private ProductPropertyValueService productPropertyValueService;
@PostMapping("/create")
@ApiOperation("创建规格名称")
@PreAuthorize("@ss.hasPermission('product:property:create')")
public CommonResult<Long> createProperty(@Valid @RequestBody ProductPropertyValueCreateReqVO createReqVO) {
return success(productPropertyValueService.createPropertyValue(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新规格名称")
@PreAuthorize("@ss.hasPermission('product:property:update')")
public CommonResult<Boolean> updateProperty(@Valid @RequestBody ProductPropertyValueUpdateReqVO updateReqVO) {
productPropertyValueService.updatePropertyValue(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除规格名称")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('product:property:delete')")
public CommonResult<Boolean> deleteProperty(@RequestParam("id") Long id) {
productPropertyValueService.deletePropertyValue(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得规格名称")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('product:property:query')")
public CommonResult<ProductPropertyValueRespVO> getProperty(@RequestParam("id") Long id) {
return success(productPropertyValueService.getPropertyValue(id));
}
@GetMapping("/page")
@ApiOperation("获得规格名称分页")
@PreAuthorize("@ss.hasPermission('product:property:query')")
public CommonResult<PageResult<ProductPropertyValueRespVO>> getPropertyValuePage(@Valid ProductPropertyValuePageReqVO pageVO) {
return success(productPropertyValueService.getPropertyValueListPage(pageVO));
}
}

View File

@@ -1,21 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
/**
* 规格名称 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class ProductPropertyBaseVO {
@ApiModelProperty(value = "规格名称")
private String name;
@ApiModelProperty(value = "状态: 0 开启 1 禁用")
private Integer status;
}

View File

@@ -1,20 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo;
import cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo.ProductPropertyValueCreateReqVO;
import lombok.*;
import io.swagger.annotations.*;
import javax.validation.constraints.NotNull;
import java.util.List;
@ApiModel("管理后台 - 规格名称创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyCreateReqVO extends ProductPropertyBaseVO {
@ApiModelProperty(value = "属性值")
@NotNull(message = "属性值不能为空")
List<ProductPropertyValueCreateReqVO> propertyValueList;
}

View File

@@ -1,29 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import com.alibaba.excel.annotation.ExcelProperty;
/**
* 规格名称 Excel VO
*
* @author 芋道源码
*/
@Data
public class ProductPropertyExcelVO {
@ExcelProperty("主键")
private Long id;
@ExcelProperty("规格名称")
private String name;
@ExcelProperty("状态: 0 开启 1 禁用")
private Integer status;
@ExcelProperty("创建时间")
private Date createTime;
}

View File

@@ -1,25 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel(value = "管理后台 - 规格名称 Excel 导出 Request VO", description = "参数和 PropertyPageReqVO 是一致的")
@Data
public class ProductPropertyExportReqVO {
@ApiModelProperty(value = "规格名称")
private String name;
@ApiModelProperty(value = "状态: 0 开启 1 禁用")
private Integer status;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "创建时间")
private Date[] createTime;
}

View File

@@ -1,23 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo;
import cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo.ProductPropertyValueRespVO;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
@ApiModel("管理后台 - 规格名称 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyRespVO extends ProductPropertyBaseVO {
@ApiModelProperty(value = "主键", required = true)
private Long id;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "属性值")
private List<ProductPropertyValueRespVO> propertyValueList;
}

View File

@@ -5,7 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import java.util.Set;
import java.util.List;
/**
* @Description: ProductPropertyViewRespVO
@@ -25,16 +25,17 @@ public class ProductPropertyViewRespVO {
public String name;
@ApiModelProperty(value = "规格属性值集合", example = "[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]")
public Set<Tuple2> propertyValues;
public List<Tuple2> propertyValues;
@Data
@ApiModel(value = "规格属性值元组")
public static class Tuple2 {
private final long v1;
private final String v2;
public Tuple2(Long v1, String v2) {
this.v1 = v1;
this.v2 = v2;
private final long id;
private final String name;
public Tuple2(Long id, String name) {
this.id = id;
this.name = name;
}
}

View File

@@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
import java.util.List;
@ApiModel("管理后台 - 规格 + 规格值 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyAndValueRespVO extends ProductPropertyBaseVO {
@ApiModelProperty(value = "规格的编号", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
/**
* 规格值的集合
*/
private List<ProductPropertyValueRespVO> values;
}

View File

@@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 规格名称 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class ProductPropertyBaseVO {
@ApiModelProperty(value = "规格名称", required = true, example = "颜色")
@NotBlank(message = "规格名称不能为空")
private String name;
@ApiModelProperty(value = "备注", example = "颜色")
private String remark;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
@NotNull(message = "状态不能为空")
private Integer status;
}

View File

@@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@ApiModel("管理后台 - 规格名称创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyCreateReqVO extends ProductPropertyBaseVO {
}

View File

@@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
@ApiModel("管理后台 - 规格名称 List Request VO")
@Data
@ToString(callSuper = true)
public class ProductPropertyListReqVO {
@ApiModelProperty(value = "规格名称", example = "颜色")
private String name;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
private Integer status;
}

View File

@@ -1,11 +1,15 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo;
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - 规格名称分页 Request VO")
@@ -14,10 +18,10 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true)
public class ProductPropertyPageReqVO extends PageParam {
@ApiModelProperty(value = "规格名称")
@ApiModelProperty(value = "规格名称", example = "颜色")
private String name;
@ApiModelProperty(value = "状态 0 开启 1 禁用")
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
private Integer status;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)

View File

@@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
@ApiModel("管理后台 - 规格 + 规格值 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyRespVO extends ProductPropertyBaseVO {
@ApiModelProperty(value = "规格的编号", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo;
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo.ProductPropertyValueCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
import lombok.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
@@ -12,12 +12,8 @@ import java.util.List;
@ToString(callSuper = true)
public class ProductPropertyUpdateReqVO extends ProductPropertyBaseVO {
@ApiModelProperty(value = "主键", required = true)
@ApiModelProperty(value = "主键", required = true, example = "1")
@NotNull(message = "主键不能为空")
private Long id;
@ApiModelProperty(value = "属性值")
@NotNull(message = "属性值不能为空")
List<ProductPropertyValueCreateReqVO> propertyValueList;
}

View File

@@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 规格值 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class ProductPropertyValueBaseVO {
@ApiModelProperty(value = "规格编号", required = true, example = "1024")
@NotNull(message = "规格编号不能为空")
private Long propertyId;
@ApiModelProperty(value = "规格值名字", required = true, example = "红色")
@NotEmpty(message = "规格值名字不能为空")
private String name;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
@NotNull(message = "状态不能为空")
private Integer status;
@ApiModelProperty(value = "备注", example = "颜色")
private String remark;
}

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo;
package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
import lombok.*;
import io.swagger.annotations.*;

View File

@@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotEmpty;
import java.util.Date;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - 规格名称值分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyValuePageReqVO extends PageParam {
@ApiModelProperty(value = "规格id", example = "1024")
private String propertyId;
@ApiModelProperty(value = "规格值", example = "红色")
private String name;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
private Integer status;
}

View File

@@ -1,8 +1,12 @@
package cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo;
package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
@ApiModel("管理后台 - 规格值 Response VO")
@Data
@@ -10,7 +14,7 @@ import io.swagger.annotations.*;
@ToString(callSuper = true)
public class ProductPropertyValueRespVO extends ProductPropertyValueBaseVO {
@ApiModelProperty(value = "主键", required = true)
@ApiModelProperty(value = "主键", required = true, example = "10")
private Long id;
@ApiModelProperty(value = "创建时间")

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo;
package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
import lombok.*;
import io.swagger.annotations.*;
@@ -10,7 +10,7 @@ import javax.validation.constraints.*;
@ToString(callSuper = true)
public class ProductPropertyValueUpdateReqVO extends ProductPropertyValueBaseVO {
@ApiModelProperty(value = "主键", required = true)
@ApiModelProperty(value = "主键", required = true, example = "1024")
@NotNull(message = "主键不能为空")
private Integer id;

View File

@@ -1,24 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
/**
* 规格值 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class ProductPropertyValueBaseVO {
@ApiModelProperty(value = "规格键id")
private Long propertyId;
@ApiModelProperty(value = "规格值名字")
private String name;
@ApiModelProperty(value = "状态: 1 开启 2 禁用")
private Integer status;
}

View File

@@ -1,27 +1,9 @@
package cn.iocoder.yudao.module.product.controller.admin.sku;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuPageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuUpdateReqVO;
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.service.sku.ProductSkuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "管理后台 - 商品 sku")
@RestController
@@ -29,57 +11,4 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Validated
public class ProductSkuController {
@Resource
private ProductSkuService ProductSkuService;
@PostMapping("/create")
@ApiOperation("创建商品sku")
@PreAuthorize("@ss.hasPermission('product:sku:create')")
public CommonResult<Long> createSku(@Valid @RequestBody ProductSkuCreateOrUpdateReqVO createReqVO) {
return success(ProductSkuService.createSku(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新商品sku")
@PreAuthorize("@ss.hasPermission('product:sku:update')")
public CommonResult<Boolean> updateSku(@Valid @RequestBody ProductSkuUpdateReqVO updateReqVO) {
ProductSkuService.updateSku(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除商品sku")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('product:sku:delete')")
public CommonResult<Boolean> deleteSku(@RequestParam("id") Long id) {
ProductSkuService.deleteSku(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得商品sku")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('product:sku:query')")
public CommonResult<ProductSkuRespVO> getSku(@RequestParam("id") Long id) {
ProductSkuDO sku = ProductSkuService.getSku(id);
return success(ProductSkuConvert.INSTANCE.convert(sku));
}
@GetMapping("/list")
@ApiOperation("获得商品sku列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('product:sku:query')")
public CommonResult<List<ProductSkuRespVO>> getSkuList(@RequestParam("ids") Collection<Long> ids) {
List<ProductSkuDO> list = ProductSkuService.getSkuList(ids);
return success(ProductSkuConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@ApiOperation("获得商品sku分页")
@PreAuthorize("@ss.hasPermission('product:sku:query')")
public CommonResult<PageResult<ProductSkuRespVO>> getSkuPage(@Valid ProductSkuPageReqVO pageVO) {
PageResult<ProductSkuDO> pageResult = ProductSkuService.getSkuPage(pageVO);
return success(ProductSkuConvert.INSTANCE.convertPage(pageResult));
}
}

View File

@@ -8,7 +8,6 @@ import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 商品 SKU Base VO提供给添加、修改、详细的子 VO 使用
@@ -21,11 +20,6 @@ public class ProductSkuBaseVO {
@NotEmpty(message = "商品 SKU 名字不能为空")
private String name;
/**
* 规格值数组
*/
private List<Property> properties;
@ApiModelProperty(value = "销售价格,单位:分", required = true, example = "1024", notes = "单位:分")
@NotNull(message = "销售价格,单位:分不能为空")
private Integer price;
@@ -39,7 +33,7 @@ public class ProductSkuBaseVO {
@ApiModelProperty(value = "条形码", example = "haha")
private String barCode;
@ApiModelProperty(value = "图片地址")
@ApiModelProperty(value = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png")
@NotNull(message = "图片地址不能为空")
private String picUrl;

View File

@@ -1,14 +1,26 @@
package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.List;
@ApiModel("管理后台 - 商品 SKU 创建/更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO {
// TODO @Luowenfeng可以不用哈如果基于规格匹配
@ApiModelProperty(value = "商品 id 更新时须有", example = "1")
private Long id;
/**
* 规格值数组
*/
private List<Property> properties;
}

View File

@@ -1,53 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* 商品sku Excel VO
*
* @author 芋道源码
*/
@Data
public class ProductSkuExcelVO {
@ExcelProperty("主键")
private Long id;
@ExcelProperty("spu编号")
private Long spuId;
// TODO @franky这个单元格可能会有点展示的问题
@ExcelProperty("规格值数组-json格式 [{propertId: , valueId: }, {propertId: , valueId: }]")
private List<Property> properties;
@ExcelProperty("销售价格,单位:分")
private Integer price;
@ExcelProperty("原价, 单位: 分")
private Integer originalPrice;
@ExcelProperty("成本价,单位: 分")
private Integer costPrice;
@ExcelProperty("条形码")
private String barCode;
@ExcelProperty("图片地址")
private String picUrl;
@ExcelProperty("状态: 0-正常 1-禁用")
private Integer status;
@ExcelProperty("创建时间")
private Date createTime;
@Data
public static class Property {
private Integer propertyId;
private Integer valueId;
}
}

View File

@@ -1,43 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel(value = "管理后台 - 商品sku Excel 导出 Request VO", description = "参数和 SkuPageReqVO 是一致的")
@Data
public class ProductSkuExportReqVO {
@ApiModelProperty(value = "spu编号")
private Long spuId;
@ApiModelProperty(value = "规格值数组-json格式 [{propertId: , valueId: }, {propertId: , valueId: }]")
private String properties;
@ApiModelProperty(value = "销售价格,单位:分")
private Integer price;
@ApiModelProperty(value = "原价, 单位: 分")
private Integer originalPrice;
@ApiModelProperty(value = "成本价,单位: 分")
private Integer costPrice;
@ApiModelProperty(value = "条形码")
private String barCode;
@ApiModelProperty(value = "图片地址")
private String picUrl;
@ApiModelProperty(value = "状态: 0-正常 1-禁用")
private Integer status;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "创建时间")
private Date[] createTime;
}

View File

@@ -1,45 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - 商品sku分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductSkuPageReqVO extends PageParam {
@ApiModelProperty(value = "spu编号")
private Long spuId;
@ApiModelProperty(value = "规格值数组-json格式 [{propertId: , valueId: }, {propertId: , valueId: }]")
private String properties;
@ApiModelProperty(value = "销售价格,单位:分")
private Integer price;
@ApiModelProperty(value = "原价, 单位: 分")
private Integer originalPrice;
@ApiModelProperty(value = "成本价,单位: 分")
private Integer costPrice;
@ApiModelProperty(value = "条形码")
private String barCode;
@ApiModelProperty(value = "图片地址")
private String picUrl;
@ApiModelProperty(value = "状态: 0-正常 1-禁用")
private Integer status;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "创建时间")
private Date[] createTime;
}

View File

@@ -1,8 +1,13 @@
package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
import java.util.List;
@ApiModel("管理后台 - 商品sku Response VO")
@Data
@@ -10,10 +15,15 @@ import io.swagger.annotations.*;
@ToString(callSuper = true)
public class ProductSkuRespVO extends ProductSkuBaseVO {
@ApiModelProperty(value = "主键", required = true)
@ApiModelProperty(value = "主键", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "创建时间")
private Date createTime;
/**
* 规格值数组
*/
private List<Property> properties;
}

View File

@@ -1,18 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
@ApiModel("管理后台 - 商品sku更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductSkuUpdateReqVO extends ProductSkuBaseVO {
@ApiModelProperty(value = "主键", required = true)
@NotNull(message = "主键不能为空")
private Long id;
}

View File

@@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.spu;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuPageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuRespVO;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
@@ -36,19 +33,19 @@ public class ProductSpuController {
@ApiOperation("创建商品 SPU")
@PreAuthorize("@ss.hasPermission('product:spu:create')")
public CommonResult<Long> createProductSpu(@Valid @RequestBody ProductSpuCreateReqVO createReqVO) {
return success(spuService.createProductSpu(createReqVO));
return success(spuService.createSpu(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新商品 SPU")
@PreAuthorize("@ss.hasPermission('product:spu:update')")
public CommonResult<Boolean> updateSpu(@Valid @RequestBody ProductSpuUpdateReqVO updateReqVO) {
spuService.updateProductSpu(updateReqVO);
spuService.updateSpu(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除商品spu")
@ApiOperation("删除商品 SPU")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('product:spu:delete')")
public CommonResult<Boolean> deleteSpu(@RequestParam("id") Long id) {
@@ -56,27 +53,36 @@ public class ProductSpuController {
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得商品spu")
@GetMapping("/get/detail")
@ApiOperation("获得商品 SPU")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('product:spu:query')")
public CommonResult<SpuRespVO> getSpu(@RequestParam("id") Long id) {
public CommonResult<ProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) {
return success(spuService.getSpuDetail(id));
}
@GetMapping("/get")
@ApiOperation("获得商品 SPU")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('product:spu:query')")
public CommonResult<ProductSpuRespVO> getSpu(@RequestParam("id") Long id) {
return success(spuService.getSpu(id));
}
@GetMapping("/list")
@ApiOperation("获得商品spu列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = Long.class)
@ApiOperation("获得商品 SPU 列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('product:spu:query')")
public CommonResult<List<SpuRespVO>> getSpuList(@RequestParam("ids") Collection<Long> ids) {
public CommonResult<List<ProductSpuRespVO>> getSpuList(@RequestParam("ids") Collection<Long> ids) {
List<ProductSpuDO> list = spuService.getSpuList(ids);
return success(ProductSpuConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@ApiOperation("获得商品spu分页")
@ApiOperation("获得商品 SPU 分页")
@PreAuthorize("@ss.hasPermission('product:spu:query')")
public CommonResult<PageResult<SpuRespVO>> getSpuPage(@Valid SpuPageReqVO pageVO) {
public CommonResult<PageResult<ProductSpuRespVO>> getSpuPage(@Valid ProductSpuPageReqVO pageVO) {
return success(spuService.getSpuPage(pageVO));
}

View File

@@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import io.swagger.annotations.ApiModelProperty;
@@ -35,8 +36,7 @@ public class ProductSpuBaseVO {
@NotNull(message = "商品分类编号不能为空")
private Long categoryId;
@ApiModelProperty(value = "商品品牌编号", required = true, example = "1")
// @NotNull(message = "商品品牌编号不能为空")
@ApiModelProperty(value = "商品品牌编号", example = "1")
private Long brandId;
@ApiModelProperty(value = "商品图片的数组", required = true)
@@ -65,10 +65,28 @@ public class ProductSpuBaseVO {
@NotNull(message = "是否展示库存不能为空")
private Boolean showStock;
@ApiModelProperty(value = "库存", required = true, example = "true")
private Integer totalStock;
@ApiModelProperty(value = "市场价", example = "1024")
private Integer marketPrice;
@ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024")
private Integer minPrice;
@ApiModelProperty(value = "最大价格,单位使用:分", required = true, example = "1024")
private Integer maxPrice;
// ========== 统计相关字段 =========
@ApiModelProperty(value = "商品销量", example = "1024")
private Integer salesCount;
@ApiModelProperty(value = "虚拟销量", required = true, example = "1024")
@NotNull(message = "虚拟销量不能为空")
private Integer virtualSalesCount;
@ApiModelProperty(value = "点击量", example = "1024")
private Integer clickCount;
}

View File

@@ -0,0 +1,64 @@
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
import java.util.List;
@ApiModel(value = "管理后台 - 商品 SPU 详细 Response VO", description = "包括关联的 SKU 等信息")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductSpuDetailRespVO extends ProductSpuBaseVO {
@ApiModelProperty(value = "主键", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "创建时间")
private Date createTime;
/**
* SKU 数组
*/
private List<Sku> skus;
@ApiModel(value = "管理后台 - 商品 SKU 详细 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public static class Sku extends ProductSkuBaseVO {
/**
* 规格的数组
*/
private List<ProductSpuDetailRespVO.Property> properties;
}
@ApiModel(value = "管理后台 - 商品规格的详细 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public static class Property extends ProductSkuBaseVO.Property {
@ApiModelProperty(value = "规格的名字", required = true, example = "颜色")
private String propertyName;
@ApiModelProperty(value = "规格值的名字", required = true, example = "蓝色")
private String valueName;
}
@ApiModelProperty(value = "分类id数组一直递归到一级父节点", example = "[1,2,4]")
private List<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\"}]}]")
private List<ProductPropertyViewRespVO> productPropertyViews;
}

View File

@@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - 商品 SPU 分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductSpuPageReqVO extends PageParam {
@ApiModelProperty(value = "商品名称")
private String name;
@ApiModelProperty(value = "商品编码", example = "yudaoyuanma")
private String code;
@ApiModelProperty(value = "分类id")
private Long categoryId;
@ApiModelProperty(value = "商品品牌编号", example = "1")
private Long brandId;
@ApiModelProperty(value = "上下架状态: 0 上架(开启) 1 下架(禁用)")
private Integer status;
}

View File

@@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
@ApiModel("管理后台 - 商品 SPU Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductSpuRespVO extends ProductSpuBaseVO {
@ApiModelProperty(value = "主键", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

View File

@@ -1,51 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - 商品spu分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SpuPageReqVO extends PageParam {
@ApiModelProperty(value = "商品名称")
private String name;
@ApiModelProperty(value = "卖点")
private String sellPoint;
@ApiModelProperty(value = "描述")
private String description;
@ApiModelProperty(value = "分类id")
private Long categoryId;
@ApiModelProperty(value = "商品主图地址,* 数组,以逗号分隔,最多上传15张")
private String picUrls;
@ApiModelProperty(value = "排序字段")
private Integer sort;
@ApiModelProperty(value = "点赞初始人数")
private Integer likeCount;
@ApiModelProperty(value = "价格 单位使用:分")
private Integer price;
@ApiModelProperty(value = "库存数量")
private Integer quantity;
@ApiModelProperty(value = "上下架状态: 0 上架(开启) 1 下架(禁用)")
private Boolean status;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "创建时间")
private Date[] createTime;
}

View File

@@ -1,41 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
@ApiModel("管理后台 - 商品spu Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SpuRespVO extends ProductSpuBaseVO {
// TODO @franky注解要完整
@ApiModelProperty(value = "主键", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "创建时间")
private Date createTime;
/**
* SKU 数组
*/
@ApiModelProperty(value = "sku 数组", example = "[{\"spuId\":4,\"properties\":[{\"propertyId\":3,\"valueId\":15},{\"propertyId\":2,\"valueId\":10}],\"price\":12,\"originalPrice\":32,\"costPrice\":22,\"barCode\":\"765670123123\",\"picUrl\":\"http://test.yudao.iocoder.cn/72938088f1ca8438837c3b51394aea43.jpg\",\"status\":0,\"id\":7,\"createTime\":1656683270000},{\"spuId\":4,\"properties\":[{\"propertyId\":3,\"valueId\":15},{\"propertyId\":2,\"valueId\":11}],\"price\":13,\"originalPrice\":33,\"costPrice\":23,\"barCode\":\"888788770999\",\"picUrl\":\"http://test.yudao.iocoder.cn/6b902c700e5d32e862b6fd9af2e1c0e4.jpg\",\"status\":0,\"id\":8,\"createTime\":1656683270000},{\"spuId\":4,\"properties\":[{\"propertyId\":3,\"valueId\":16},{\"propertyId\":2,\"valueId\":10}],\"price\":14,\"originalPrice\":34,\"costPrice\":24,\"barCode\":\"9999981212\",\"picUrl\":\"http://test.yudao.iocoder.cn/eddf3c79b1917160d94d05244e1f47da.jpg\",\"status\":0,\"id\":9,\"createTime\":1656683270000},{\"spuId\":4,\"properties\":[{\"propertyId\":3,\"valueId\":16},{\"propertyId\":2,\"valueId\":11}],\"price\":15,\"originalPrice\":35,\"costPrice\":25,\"barCode\":\"4444121212\",\"picUrl\":\"http://test.yudao.iocoder.cn/88ac3eb068ea9cfac4726879b2776ccf.jpg\",\"status\":0,\"id\":10,\"createTime\":1656683270000}]")
private List<ProductSkuRespVO> skus;
@ApiModelProperty(value = "分类id数组一直递归到一级父节点", example = "[1,2,4]")
private LinkedList<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\"}]}]")
private List<ProductPropertyViewRespVO> productPropertyViews;
}

View File

@@ -30,7 +30,7 @@ public class AppCategoryController {
@GetMapping("/list")
@ApiOperation("获得商品分类列表")
public CommonResult<List<AppCategoryRespVO>> getProductCategoryList() {
List<ProductCategoryDO> list = categoryService.getEnableProductCategoryList();
List<ProductCategoryDO> list = categoryService.getEnableCategoryList();
list.sort(Comparator.comparing(ProductCategoryDO::getSort));
return success(ProductCategoryConvert.INSTANCE.convertList03(list));
}

View File

@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.product.controller.app.spu;
import cn.hutool.core.bean.BeanUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuRespVO;
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.AppSpuRespVO;

View File

@@ -1,10 +1,9 @@
package cn.iocoder.yudao.module.product.controller.app.spu.vo;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuRespVO;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* <p>
@@ -16,7 +15,7 @@ import lombok.ToString;
@ApiModel("App - 商品spu Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
public class AppSpuRespVO extends SpuRespVO {
public class AppSpuRespVO extends ProductSpuRespVO {
}

View File

@@ -1,13 +1,14 @@
package cn.iocoder.yudao.module.product.convert.property;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.ProductPropertyUpdateReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.*;
import java.util.List;
/**
* 规格名称 Convert
@@ -29,6 +30,4 @@ public interface ProductPropertyConvert {
PageResult<ProductPropertyRespVO> convertPage(PageResult<ProductPropertyDO> page);
List<ProductPropertyExcelVO> convertList02(List<ProductPropertyDO> list);
}

View File

@@ -4,10 +4,12 @@ import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo.*;
/**
* 规格值 Convert

View File

@@ -2,13 +2,12 @@ package cn.iocoder.yudao.module.product.convert.sku;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.api.sku.dto.SkuInfoRespDTO;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuExcelVO;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuUpdateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuDetailRespVO;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.List;
@@ -25,18 +24,17 @@ public interface ProductSkuConvert {
ProductSkuDO convert(ProductSkuCreateOrUpdateReqVO bean);
ProductSkuDO convert(ProductSkuUpdateReqVO bean);
@Mapping(source = "properties", target = "properties")
ProductSkuRespVO convert(ProductSkuDO bean);
List<ProductSkuRespVO> convertList(List<ProductSkuDO> list);
List<ProductSkuDO> convertSkuDOList(List<ProductSkuCreateOrUpdateReqVO> list);
PageResult<ProductSkuRespVO> convertPage(PageResult<ProductSkuDO> page);
ProductSkuRespDTO convert02(ProductSkuDO bean);
List<ProductSkuExcelVO> convertList02(List<ProductSkuDO> list);
List<ProductSkuRespDTO> convertList02(List<ProductSkuDO> list);
List<ProductSpuDetailRespVO.Sku> convertList03(List<ProductSkuDO> list);
List<SkuInfoRespDTO> convertList03(List<ProductSkuDO> list);

View File

@@ -25,13 +25,13 @@ public interface ProductSpuConvert {
ProductSpuDO convert(ProductSpuUpdateReqVO bean);
SpuRespVO convert(ProductSpuDO bean);
ProductSpuRespVO convert(ProductSpuDO bean);
List<SpuRespVO> convertList(List<ProductSpuDO> list);
List<ProductSpuRespVO> convertList(List<ProductSpuDO> list);
PageResult<SpuRespVO> convertPage(PageResult<ProductSpuDO> page);
PageResult<ProductSpuRespVO> convertPage(PageResult<ProductSpuDO> page);
SpuPageReqVO convert(AppSpuPageReqVO bean);
ProductSpuPageReqVO convert(AppSpuPageReqVO bean);
AppSpuPageRespVO convertAppResp(ProductSpuDO list);

View File

@@ -37,6 +37,10 @@ public class ProductPropertyDO extends BaseDO {
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
/**
* 备注
*/
private String remark;
// TODO 芋艿rule规格属性 (发布商品时,和 SKU 关联);规格参数(搜索商品时,与 Category 关联搜索)

View File

@@ -44,5 +44,10 @@ public class ProductPropertyValueDO extends BaseDO {
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
/**
* 备注
*
*/
private String remark;
}

View File

@@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.product.dal.dataobject.sku;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
@@ -9,7 +10,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import lombok.*;
import java.util.List;
@@ -19,7 +20,7 @@ import java.util.List;
*
* @author 芋道源码
*/
@TableName("product_sku")
@TableName(value = "product_sku",autoResultMap = true)
@KeySequence("product_sku_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@@ -40,14 +41,14 @@ public class ProductSkuDO extends BaseDO {
private String name;
/**
* SPU 编号
*
* <p>
* 关联 {@link ProductSpuDO#getId()}
*/
private Long spuId;
/**
* 规格值数组JSON 格式
*/
@TableField(typeHandler = JacksonTypeHandler.class)
@TableField(typeHandler = PropertyTypeHandler.class)
private List<Property> properties;
/**
* 销售价格,单位:分
@@ -71,7 +72,7 @@ public class ProductSkuDO extends BaseDO {
private String picUrl;
/**
* SKU 状态
*
* <p>
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
@@ -100,19 +101,34 @@ public class ProductSkuDO extends BaseDO {
/**
* 属性编号
*
* <p>
* 关联 {@link ProductPropertyDO#getId()}
*/
private Long propertyId;
/**
* 属性值编号
*
* <p>
* 关联 {@link ProductPropertyValueDO#getId()}
*/
private Long valueId;
}
// TODO @芋艿:可以找一些新的思路
public static class PropertyTypeHandler extends AbstractJsonTypeHandler<Object> {
@Override
protected Object parse(String json) {
return JsonUtils.parseArray(json, Property.class);
}
@Override
protected String toJson(Object obj) {
return JsonUtils.toJsonString(obj);
}
}
// TODO ========== 待定字段yv =========
// TODO brokerage一级返佣
// TODO brokerage_two二级返佣

View File

@@ -3,10 +3,13 @@ package cn.iocoder.yudao.module.product.dal.mysql.brand;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandListReqVO;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface ProductBrandMapper extends BaseMapperX<ProductBrandDO> {
@@ -18,4 +21,14 @@ public interface ProductBrandMapper extends BaseMapperX<ProductBrandDO> {
.orderByDesc(ProductBrandDO::getId));
}
default List<ProductBrandDO> selectList(ProductBrandListReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<ProductBrandDO>()
.likeIfPresent(ProductBrandDO::getName, reqVO.getName()));
}
default ProductBrandDO selectByName(String name) {
return selectOne(ProductBrandDO::getName, name);
}
}

View File

@@ -1,13 +1,11 @@
package cn.iocoder.yudao.module.product.dal.mysql.property;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.*;
/**
* 规格名称 Mapper
@@ -25,12 +23,4 @@ public interface ProductPropertyMapper extends BaseMapperX<ProductPropertyDO> {
.orderByDesc(ProductPropertyDO::getId));
}
default List<ProductPropertyDO> selectList(ProductPropertyExportReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<ProductPropertyDO>()
.likeIfPresent(ProductPropertyDO::getName, reqVO.getName())
.eqIfPresent(ProductPropertyDO::getStatus, reqVO.getStatus())
.betweenIfPresent(ProductPropertyDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ProductPropertyDO::getId));
}
}

View File

@@ -1,7 +1,9 @@
package cn.iocoder.yudao.module.product.dal.mysql.propertyvalue;
package cn.iocoder.yudao.module.product.dal.mysql.property;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
import org.apache.ibatis.annotations.Mapper;
@@ -16,17 +18,25 @@ import java.util.List;
public interface ProductPropertyValueMapper extends BaseMapperX<ProductPropertyValueDO> {
// TODO @franky方法名selectListByXXXmapper 的操作都是 crud
default List<ProductPropertyValueDO> getPropertyValueListByPropertyId(List<Long> propertyIds){
default List<ProductPropertyValueDO> getPropertyValueListByPropertyId(List<Long> propertyIds) {
// TODO @franky调用父类的 selectList
return selectList(new LambdaQueryWrapperX<ProductPropertyValueDO>()
.inIfPresent(ProductPropertyValueDO::getPropertyId, propertyIds));
}
default void deletePropertyValueByPropertyId(Long propertyId){
default void deletePropertyValueByPropertyId(Long propertyId) {
// TODO @frankydelete(new ) 即可
LambdaQueryWrapperX<ProductPropertyValueDO> queryWrapperX = new LambdaQueryWrapperX<>();
queryWrapperX.eq(ProductPropertyValueDO::getPropertyId, propertyId)
.eq(ProductPropertyValueDO::getDeleted, false);
delete(queryWrapperX);
}
default PageResult<ProductPropertyValueDO> selectPage(ProductPropertyValuePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ProductPropertyValueDO>()
.eqIfPresent(ProductPropertyValueDO::getPropertyId, reqVO.getPropertyId())
.likeIfPresent(ProductPropertyValueDO::getName, reqVO.getName())
.eqIfPresent(ProductPropertyValueDO::getStatus, reqVO.getStatus())
.orderByDesc(ProductPropertyValueDO::getId));
}
}

View File

@@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.product.dal.mysql.sku;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.product.api.sku.dto.SkuDecrementStockBatchReqDTO;
@@ -9,40 +8,23 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collections;
import java.util.List;
/**
* 商品sku Mapper
* 商品 SKU Mapper
*
* @author 芋道源码
*/
@Mapper
public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> {
default PageResult<ProductSkuDO> selectPage(ProductSkuPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ProductSkuDO>()
.eqIfPresent(ProductSkuDO::getSpuId, reqVO.getSpuId())
.eqIfPresent(ProductSkuDO::getProperties, reqVO.getProperties())
.eqIfPresent(ProductSkuDO::getPrice, reqVO.getPrice())
// .eqIfPresent(ProductSkuDO::getOriginalPrice, reqVO.getOriginalPrice())
// .eqIfPresent(ProductSkuDO::getCostPrice, reqVO.getCostPrice())
.eqIfPresent(ProductSkuDO::getBarCode, reqVO.getBarCode())
.eqIfPresent(ProductSkuDO::getPicUrl, reqVO.getPicUrl())
.eqIfPresent(ProductSkuDO::getStatus, reqVO.getStatus())
.betweenIfPresent(ProductSkuDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ProductSkuDO::getId));
}
// TODO @franky方法名 selectList; 可以直接调用 selectList
default List<ProductSkuDO> selectBySpuIds(List<Long> spuIds) {
return selectList(new LambdaQueryWrapperX<ProductSkuDO>()
.inIfPresent(ProductSkuDO::getSpuId, spuIds));
default List<ProductSkuDO> selectListBySpuIds(List<Long> spuIds) {
return selectList(ProductSkuDO::getSpuId, spuIds);
}
default List<ProductSkuDO> selectBySpuId(Long spuIds) {
return selectBySpuIds(Collections.singletonList(spuIds));
default List<ProductSkuDO> selectListBySpuId(Long spuId) {
return selectList(ProductSkuDO::getSpuId, spuId);
}
default void deleteBySpuId(Long spuId) {

View File

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.product.dal.mysql.spu;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuPageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import org.apache.ibatis.annotations.Mapper;
@@ -15,20 +15,12 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
default PageResult<ProductSpuDO> selectPage(SpuPageReqVO reqVO) {
default PageResult<ProductSpuDO> selectPage(ProductSpuPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ProductSpuDO>()
.likeIfPresent(ProductSpuDO::getName, reqVO.getName())
.eqIfPresent(ProductSpuDO::getSellPoint, reqVO.getSellPoint())
.eqIfPresent(ProductSpuDO::getDescription, reqVO.getDescription())
.eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId())
.eqIfPresent(ProductSpuDO::getPicUrls, reqVO.getPicUrls())
.eqIfPresent(ProductSpuDO::getSort, reqVO.getSort())
// .eqIfPresent(ProductSpuDO::getLikeCount, reqVO.getLikeCount())
// .eqIfPresent(ProductSpuDO::getPrice, reqVO.getPrice())
// .eqIfPresent(ProductSpuDO::getQuantity, reqVO.getQuantity())
.eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus())
.betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ProductSpuDO::getId));
.orderByDesc(ProductSpuDO::getSort));
}
}

View File

@@ -1,9 +1,7 @@
package cn.iocoder.yudao.module.product.service.brand;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandUpdateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*;
import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
import javax.validation.Valid;
@@ -23,7 +21,7 @@ public interface ProductBrandService {
* @param createReqVO 创建信息
* @return 编号
*/
Long createProductBrand(@Valid ProductBrandCreateReqVO createReqVO);
Long createBrand(@Valid ProductBrandCreateReqVO createReqVO);
/**
* 更新品牌
@@ -55,6 +53,21 @@ public interface ProductBrandService {
*/
List<ProductBrandDO> getBrandList(Collection<Long> ids);
/**
* 获得品牌列表
*
* @param listReqVO 请求参数
* @return 品牌列表
*/
List<ProductBrandDO> getBrandList(ProductBrandListReqVO listReqVO);
/**
* 验证选择的商品分类是否合法
*
* @param id 分类编号
*/
void validateProductBrand(Long id);
/**
* 获得品牌分页
*

View File

@@ -1,12 +1,15 @@
package cn.iocoder.yudao.module.product.service.brand;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandListReqVO;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandUpdateReqVO;
import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
import cn.iocoder.yudao.module.product.dal.mysql.brand.ProductBrandMapper;
import com.google.common.annotations.VisibleForTesting;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -15,7 +18,7 @@ import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_BRAND_NOT_EXISTS;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
/**
* 品牌 Service 实现类
@@ -30,7 +33,10 @@ public class ProductBrandServiceImpl implements ProductBrandService {
private ProductBrandMapper brandMapper;
@Override
public Long createProductBrand(ProductBrandCreateReqVO createReqVO) {
public Long createBrand(ProductBrandCreateReqVO createReqVO) {
// 校验
validateBrandNameUnique(null, createReqVO.getName());
// 插入
ProductBrandDO brand = ProductBrandConvert.INSTANCE.convert(createReqVO);
brandMapper.insert(brand);
@@ -42,6 +48,7 @@ public class ProductBrandServiceImpl implements ProductBrandService {
public void updateBrand(ProductBrandUpdateReqVO updateReqVO) {
// 校验存在
validateBrandExists(updateReqVO.getId());
validateBrandNameUnique(updateReqVO.getId(), updateReqVO.getName());
// 更新
ProductBrandDO updateObj = ProductBrandConvert.INSTANCE.convert(updateReqVO);
brandMapper.updateById(updateObj);
@@ -50,14 +57,29 @@ public class ProductBrandServiceImpl implements ProductBrandService {
@Override
public void deleteBrand(Long id) {
// 校验存在
this.validateBrandExists(id);
validateBrandExists(id);
// 删除
brandMapper.deleteById(id);
}
private void validateBrandExists(Long id) {
if (brandMapper.selectById(id) == null) {
throw exception(PRODUCT_BRAND_NOT_EXISTS);
throw exception(BRAND_NOT_EXISTS);
}
}
@VisibleForTesting
public void validateBrandNameUnique(Long id, String name) {
ProductBrandDO brand = brandMapper.selectByName(name);
if (brand == null) {
return;
}
// 如果 id 为空,说明不用比较是否为相同 id 的字典类型
if (id == null) {
throw exception(BRAND_NAME_EXISTS);
}
if (!brand.getId().equals(id)) {
throw exception(BRAND_NAME_EXISTS);
}
}
@@ -71,6 +93,22 @@ public class ProductBrandServiceImpl implements ProductBrandService {
return brandMapper.selectBatchIds(ids);
}
@Override
public List<ProductBrandDO> getBrandList(ProductBrandListReqVO listReqVO) {
return brandMapper.selectList(listReqVO);
}
@Override
public void validateProductBrand(Long id) {
ProductBrandDO brand = brandMapper.selectById(id);
if (brand == null) {
throw exception(BRAND_NOT_EXISTS);
}
if (brand.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) {
throw exception(BRAND_DISABLED);
}
}
@Override
public PageResult<ProductBrandDO> getBrandPage(ProductBrandPageReqVO pageReqVO) {
return brandMapper.selectPage(pageReqVO);

View File

@@ -22,21 +22,21 @@ public interface ProductCategoryService {
* @param createReqVO 创建信息
* @return 编号
*/
Long createProductCategory(@Valid ProductCategoryCreateReqVO createReqVO);
Long createCategory(@Valid ProductCategoryCreateReqVO createReqVO);
/**
* 更新商品分类
*
* @param updateReqVO 更新信息
*/
void updateProductCategory(@Valid ProductCategoryUpdateReqVO updateReqVO);
void updateCategory(@Valid ProductCategoryUpdateReqVO updateReqVO);
/**
* 删除商品分类
*
* @param id 编号
*/
void deleteProductCategory(Long id);
void deleteCategory(Long id);
/**
* 获得商品分类
@@ -44,7 +44,7 @@ public interface ProductCategoryService {
* @param id 编号
* @return 商品分类
*/
ProductCategoryDO getProductCategory(Long id);
ProductCategoryDO getCategory(Long id);
/**
* 获得商品分类列表
@@ -52,7 +52,7 @@ public interface ProductCategoryService {
* @param ids 编号
* @return 商品分类列表
*/
List<ProductCategoryDO> getEnableProductCategoryList(Collection<Long> ids);
List<ProductCategoryDO> getEnableCategoryList(Collection<Long> ids);
/**
* 获得商品分类列表
@@ -60,20 +60,21 @@ public interface ProductCategoryService {
* @param listReqVO 查询条件
* @return 商品分类列表
*/
List<ProductCategoryDO> getEnableProductCategoryList(ProductCategoryListReqVO listReqVO);
List<ProductCategoryDO> getEnableCategoryList(ProductCategoryListReqVO listReqVO);
/**
* 验证选择的商品分类是否合法
* 验证选择的商品分类的级别是否合法
* 例如说,商品发布的时候,必须在第 3 级别
*
* @param id 分类编号
*/
void validateProductCategory(Long id);
void validateCategoryLevel(Long id);
/**
* 获得开启状态的商品分类列表
*
* @return 商品分类列表
*/
List<ProductCategoryDO> getEnableProductCategoryList();
List<ProductCategoryDO> getEnableCategoryList();
}

View File

@@ -32,7 +32,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
private ProductCategoryMapper productCategoryMapper;
@Override
public Long createProductCategory(ProductCategoryCreateReqVO createReqVO) {
public Long createCategory(ProductCategoryCreateReqVO createReqVO) {
// 校验父分类存在
validateParentProductCategory(createReqVO.getParentId());
@@ -44,7 +44,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
}
@Override
public void updateProductCategory(ProductCategoryUpdateReqVO updateReqVO) {
public void updateCategory(ProductCategoryUpdateReqVO updateReqVO) {
// 校验分类是否存在
validateProductCategoryExists(updateReqVO.getId());
// 校验父分类存在
@@ -56,14 +56,14 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
}
@Override
public void deleteProductCategory(Long id) {
public void deleteCategory(Long id) {
// 校验分类是否存在
validateProductCategoryExists(id);
// 校验是否还有子分类
if (productCategoryMapper.selectCountByParentId(id) > 0) {
throw exception(PRODUCT_CATEGORY_EXISTS_CHILDREN);
throw exception(CATEGORY_EXISTS_CHILDREN);
}
// TODO 芋艿 补充只有不存在商品才可以删除
// 删除
productCategoryMapper.deleteById(id);
}
@@ -76,61 +76,69 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
// 父分类不存在
ProductCategoryDO category = productCategoryMapper.selectById(id);
if (category == null) {
throw exception(PRODUCT_CATEGORY_PARENT_NOT_EXISTS);
throw exception(CATEGORY_PARENT_NOT_EXISTS);
}
// 父分类不能是二级分类
if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) {
throw exception(PRODUCT_CATEGORY_PARENT_NOT_FIRST_LEVEL);
throw exception(CATEGORY_PARENT_NOT_FIRST_LEVEL);
}
}
private void validateProductCategoryExists(Long id) {
ProductCategoryDO category = productCategoryMapper.selectById(id);
if (category == null) {
throw exception(PRODUCT_CATEGORY_NOT_EXISTS);
throw exception(CATEGORY_NOT_EXISTS);
}
}
@Override
public void validateProductCategory(Long id) {
Integer level = categoryLevel(id, 1);
if(level < 3){
throw exception(PRODUCT_CATEGORY_LEVEL);
public void validateCategoryLevel(Long id) {
Integer level = getProductCategoryLevel(id, 1);
if (level < 3){
throw exception(CATEGORY_LEVEL_ERROR);
}
}
// 校验分类级别
private Integer categoryLevel(Long id, int level){
// TODO @Luowenfeng建议使用 for 循环,避免递归
/**
* 获得商品分类的级别
*
* @param id 商品分类的编号
* @return 级别
*/
private Integer getProductCategoryLevel(Long id, int level){
ProductCategoryDO category = productCategoryMapper.selectById(id);
if (category == null) {
throw exception(PRODUCT_CATEGORY_NOT_EXISTS);
throw exception(CATEGORY_NOT_EXISTS);
}
// TODO Luowenfeng去掉是否开启它不影响级别哈
if (ObjectUtil.notEqual(category.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
throw exception(PRODUCT_CATEGORY_DISABLED);
throw exception(CATEGORY_DISABLED);
}
if(category.getParentId() == 0) {
// TODO Luowenfeng不使用 0 直接比较哈,使用枚举
if (category.getParentId() == 0) {
return level;
}
return categoryLevel(category.getParentId(), ++level);
return getProductCategoryLevel(category.getParentId(), ++level);
}
@Override
public ProductCategoryDO getProductCategory(Long id) {
public ProductCategoryDO getCategory(Long id) {
return productCategoryMapper.selectById(id);
}
@Override
public List<ProductCategoryDO> getEnableProductCategoryList(Collection<Long> ids) {
public List<ProductCategoryDO> getEnableCategoryList(Collection<Long> ids) {
return productCategoryMapper.selectBatchIds(ids);
}
@Override
public List<ProductCategoryDO> getEnableProductCategoryList(ProductCategoryListReqVO listReqVO) {
public List<ProductCategoryDO> getEnableCategoryList(ProductCategoryListReqVO listReqVO) {
return productCategoryMapper.selectList(listReqVO);
}
@Override
public List<ProductCategoryDO> getEnableProductCategoryList() {
public List<ProductCategoryDO> getEnableCategoryList() {
return productCategoryMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
}

Some files were not shown because too many files have changed in this diff Show More