mall:完善商品分类的后端接口
parent
1976571ae8
commit
6a0f713452
|
@ -3,16 +3,18 @@ package cn.iocoder.yudao.module.product.enums;
|
|||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
|
||||
/**
|
||||
* product 错误码枚举类
|
||||
* <p>
|
||||
* Product 错误码枚举类
|
||||
*
|
||||
* product 系统,使用 1-008-000-000 段
|
||||
*/
|
||||
public interface ErrorCodeConstants {
|
||||
|
||||
// ========== 商品分类相关 1008001000============
|
||||
ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在");
|
||||
ErrorCode CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1008001001, "父分类不存在");
|
||||
ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001002, "存在子分类,无法删除");
|
||||
// ========== 商品分类相关 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, "商品分类({})已禁用,无法使用");
|
||||
|
||||
// ========== 品牌相关编号 1008002000 ==========
|
||||
ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在");
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.category;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
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.category.vo.*;
|
||||
import cn.iocoder.yudao.module.product.convert.category.CategoryConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
|
||||
import cn.iocoder.yudao.module.product.service.category.CategoryService;
|
||||
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.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
|
||||
@RequestMapping("/product/category")
|
||||
@Validated
|
||||
public class CategoryController {
|
||||
|
||||
@Resource
|
||||
private CategoryService categoryService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建商品分类")
|
||||
@PreAuthorize("@ss.hasPermission('product:category:create')")
|
||||
public CommonResult<Long> createCategory(@Valid @RequestBody CategoryCreateReqVO createReqVO) {
|
||||
return success(categoryService.createCategory(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation("更新商品分类")
|
||||
@PreAuthorize("@ss.hasPermission('product:category:update')")
|
||||
public CommonResult<Boolean> updateCategory(@Valid @RequestBody CategoryUpdateReqVO updateReqVO) {
|
||||
categoryService.updateCategory(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除商品分类")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('product:category:delete')")
|
||||
public CommonResult<Boolean> deleteCategory(@RequestParam("id") Long id) {
|
||||
categoryService.deleteCategory(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得商品分类")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('product:category:query')")
|
||||
public CommonResult<CategoryRespVO> getCategory(@RequestParam("id") Long id) {
|
||||
CategoryDO category = categoryService.getCategory(id);
|
||||
return success(CategoryConvert.INSTANCE.convert(category));
|
||||
}
|
||||
|
||||
// TODO @JeromeSoar:这应该是个 app 的接口,提供商品分类的树结构。这个调整下,后端只返回列表,前端构建 tree。注意,不需要返回创建时间、是否开启等无关字段。
|
||||
// TODO @YunaiV: 这个是在管理端展示了一个类似菜单的分类树列表, treeListReqVO 只是查询参数的封装命名,返给前端的是列表数据。PS: 这里 /page 接口没有使用到。
|
||||
@GetMapping("/listByQuery")
|
||||
@ApiOperation("获得商品分类列表")
|
||||
@PreAuthorize("@ss.hasPermission('product:category:query')")
|
||||
public CommonResult<List<CategoryRespVO>> listByQuery(@Valid CategoryTreeListReqVO treeListReqVO) {
|
||||
List<CategoryDO> list = categoryService.getCategoryTreeList(treeListReqVO);
|
||||
list.sort(Comparator.comparing(CategoryDO::getSort));
|
||||
return success(CategoryConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@ApiOperation("导出商品分类 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('product:category:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportCategoryExcel(@Valid CategoryExportReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<CategoryDO> list = categoryService.getCategoryList(exportReqVO);
|
||||
// 导出 Excel
|
||||
List<CategoryExcelVO> datas = CategoryConvert.INSTANCE.convertList02(list);
|
||||
ExcelUtils.write(response, "商品分类.xls", "数据", CategoryExcelVO.class, datas);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.category;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.convert.category.CategoryConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
|
||||
import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
|
||||
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.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Api(tags = "管理后台 - 商品分类")
|
||||
@RestController
|
||||
@RequestMapping("/product/category")
|
||||
@Validated
|
||||
public class ProductCategoryController {
|
||||
|
||||
@Resource
|
||||
private ProductCategoryService categoryService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建商品分类")
|
||||
@PreAuthorize("@ss.hasPermission('product:category:create')")
|
||||
public CommonResult<Long> createProductCategory(@Valid @RequestBody ProductCategoryCreateReqVO createReqVO) {
|
||||
return success(categoryService.createProductCategory(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation("更新商品分类")
|
||||
@PreAuthorize("@ss.hasPermission('product:category:update')")
|
||||
public CommonResult<Boolean> updateProductCategory(@Valid @RequestBody ProductCategoryUpdateReqVO updateReqVO) {
|
||||
categoryService.updateProductCategory(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@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);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@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);
|
||||
return success(CategoryConvert.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);
|
||||
list.sort(Comparator.comparing(ProductCategoryDO::getSort));
|
||||
return success(CategoryConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.category.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* 商品分类 Excel VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class CategoryExcelVO {
|
||||
|
||||
@ExcelProperty("分类编号")
|
||||
private Long id;
|
||||
|
||||
@ExcelProperty("父分类编号")
|
||||
private Long parentId;
|
||||
|
||||
@ExcelProperty("分类名称")
|
||||
private String name;
|
||||
|
||||
@ExcelProperty("分类图标")
|
||||
private String icon;
|
||||
|
||||
@ExcelProperty("分类图片")
|
||||
private String bannerUrl;
|
||||
|
||||
@ExcelProperty("分类排序")
|
||||
private Integer sort;
|
||||
|
||||
@ExcelProperty("分类描述")
|
||||
private String description;
|
||||
|
||||
@ExcelProperty(value = "开启状态", converter = DictConvert.class)
|
||||
@DictFormat("common_status") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中
|
||||
private Integer status;
|
||||
|
||||
@ExcelProperty("创建时间")
|
||||
private Date createTime;
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.category.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
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(value = "管理后台 - 商品分类 Excel 导出 Request VO", description = "参数和 CategoryPageReqVO 是一致的")
|
||||
@Data
|
||||
public class CategoryExportReqVO {
|
||||
|
||||
@ApiModelProperty(value = "分类名称", example = "办公文具")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "开启状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Date[] createTime;
|
||||
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.category.vo;
|
||||
|
||||
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")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CategoryPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "分类名称", example = "办公文具")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "开启状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Date[] createTime;
|
||||
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.category.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
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;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "管理后台 - 商品分类列表查询 Request VO", description = "参数和 CategoryPageReqVO 是一致的")
|
||||
public class CategoryTreeListReqVO extends CategoryExportReqVO {
|
||||
|
||||
@ApiModelProperty(value = "分类名称", example = "办公文具")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "开启状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Date[] createTime;
|
||||
}
|
|
@ -11,7 +11,7 @@ import javax.validation.constraints.NotNull;
|
|||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class CategoryBaseVO {
|
||||
public class ProductCategoryBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "父分类编号", required = true, example = "1")
|
||||
@NotNull(message = "父分类编号不能为空")
|
||||
|
@ -21,13 +21,9 @@ public class CategoryBaseVO {
|
|||
@NotBlank(message = "分类名称不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "分类图标")
|
||||
@NotBlank(message = "分类图标不能为空")
|
||||
private String icon;
|
||||
|
||||
@ApiModelProperty(value = "分类图片", required = true)
|
||||
@NotBlank(message = "分类图片不能为空")
|
||||
private String bannerUrl;
|
||||
private String picUrl;
|
||||
|
||||
@ApiModelProperty(value = "分类排序", required = true, example = "1")
|
||||
private Integer sort;
|
|
@ -1,14 +1,12 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.category.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
@ApiModel("管理后台 - 商品分类创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CategoryCreateReqVO extends CategoryBaseVO {
|
||||
public class ProductCategoryCreateReqVO extends ProductCategoryBaseVO {
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.category.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@ApiModel(value = "管理后台 - 商品分类列表查询 Request VO")
|
||||
@Data
|
||||
public class ProductCategoryListReqVO {
|
||||
|
||||
@ApiModelProperty(value = "分类名称", example = "办公文具")
|
||||
private String name;
|
||||
|
||||
}
|
|
@ -8,7 +8,7 @@ import io.swagger.annotations.*;
|
|||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CategoryRespVO extends CategoryBaseVO {
|
||||
public class ProductCategoryRespVO extends ProductCategoryBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "分类编号", required = true, example = "2")
|
||||
private Long id;
|
|
@ -1,7 +1,6 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.category.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
|
@ -9,7 +8,7 @@ import javax.validation.constraints.*;
|
|||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CategoryUpdateReqVO extends CategoryBaseVO {
|
||||
public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "分类编号", required = true, example = "2")
|
||||
@NotNull(message = "分类编号不能为空")
|
|
@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.product.controller.app.category;
|
|||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryListRespVO;
|
||||
import cn.iocoder.yudao.module.product.convert.category.CategoryConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
|
||||
import cn.iocoder.yudao.module.product.service.category.CategoryService;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
|
||||
import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
@ -25,13 +25,13 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
|||
public class AppCategoryController {
|
||||
|
||||
@Resource
|
||||
private CategoryService categoryService;
|
||||
private ProductCategoryService categoryService;
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获得商品分类列表")
|
||||
public CommonResult<List<AppCategoryListRespVO>> listByQuery() {
|
||||
List<CategoryDO> list = categoryService.getCategoryList();
|
||||
list.sort(Comparator.comparing(CategoryDO::getSort));
|
||||
List<ProductCategoryDO> list = categoryService.getEnableProductCategoryList();
|
||||
list.sort(Comparator.comparing(ProductCategoryDO::getSort));
|
||||
return success(CategoryConvert.INSTANCE.convertList03(list));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package cn.iocoder.yudao.module.product.convert.category;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryListRespVO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.*;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品分类 Convert
|
||||
|
@ -20,17 +20,13 @@ public interface CategoryConvert {
|
|||
|
||||
CategoryConvert INSTANCE = Mappers.getMapper(CategoryConvert.class);
|
||||
|
||||
CategoryDO convert(CategoryCreateReqVO bean);
|
||||
ProductCategoryDO convert(ProductCategoryCreateReqVO bean);
|
||||
|
||||
CategoryDO convert(CategoryUpdateReqVO bean);
|
||||
ProductCategoryDO convert(ProductCategoryUpdateReqVO bean);
|
||||
|
||||
CategoryRespVO convert(CategoryDO bean);
|
||||
ProductCategoryRespVO convert(ProductCategoryDO bean);
|
||||
|
||||
List<CategoryRespVO> convertList(List<CategoryDO> list);
|
||||
List<ProductCategoryRespVO> convertList(List<ProductCategoryDO> list);
|
||||
|
||||
PageResult<CategoryRespVO> convertPage(PageResult<CategoryDO> page);
|
||||
|
||||
List<CategoryExcelVO> convertList02(List<CategoryDO> list);
|
||||
|
||||
List<AppCategoryListRespVO> convertList03(List<CategoryDO> list);
|
||||
List<AppCategoryListRespVO> convertList03(List<ProductCategoryDO> list);
|
||||
}
|
||||
|
|
|
@ -6,10 +6,13 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
|||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
// TODO @JeromeSoar:Product 前缀
|
||||
/**
|
||||
* 商品分类 DO
|
||||
*
|
||||
* 商品分类一共两级:
|
||||
* 1)一级分类:{@link #parentId} 等于 0
|
||||
* 2)二级分类:{@link #parentId} 等于父分类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("product_category")
|
||||
|
@ -19,7 +22,12 @@ import lombok.*;
|
|||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CategoryDO extends BaseDO {
|
||||
public class ProductCategoryDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 父分类编号 - 根分类
|
||||
*/
|
||||
public static final Long PARENT_ID_NULL = 0L;
|
||||
|
||||
/**
|
||||
* 分类编号
|
||||
|
@ -35,15 +43,12 @@ public class CategoryDO extends BaseDO {
|
|||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 分类图标
|
||||
*/
|
||||
private String icon;
|
||||
/**
|
||||
* 分类 Banner 图片
|
||||
* 分类图片
|
||||
*
|
||||
* 第一层的商品分类,会有该字段,用于用户 App 展示
|
||||
* 一级分类:推荐 200 x 100 分辨率
|
||||
* 二级分类:推荐 100 x 100 分辨率
|
||||
*/
|
||||
private String bannerUrl;
|
||||
private String picUrl;
|
||||
/**
|
||||
* 分类排序
|
||||
*/
|
|
@ -1,40 +0,0 @@
|
|||
package cn.iocoder.yudao.module.product.dal.mysql.category;
|
||||
|
||||
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.category.vo.CategoryExportReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品分类 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface CategoryMapper extends BaseMapperX<CategoryDO> {
|
||||
|
||||
default PageResult<CategoryDO> selectPage(CategoryPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<CategoryDO>()
|
||||
.likeIfPresent(CategoryDO::getName, reqVO.getName())
|
||||
.eqIfPresent(CategoryDO::getStatus, reqVO.getStatus())
|
||||
.betweenIfPresent(CategoryDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(CategoryDO::getId));
|
||||
}
|
||||
|
||||
default List<CategoryDO> selectList(CategoryExportReqVO reqVO) {
|
||||
return selectList(new LambdaQueryWrapperX<CategoryDO>()
|
||||
.likeIfPresent(CategoryDO::getName, reqVO.getName())
|
||||
.eqIfPresent(CategoryDO::getStatus, reqVO.getStatus())
|
||||
.betweenIfPresent(CategoryDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(CategoryDO::getId));
|
||||
}
|
||||
|
||||
default Long selectCountByParentId(Long parentId) {
|
||||
return selectCount(CategoryDO::getParentId, parentId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package cn.iocoder.yudao.module.product.dal.mysql.category;
|
||||
|
||||
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.category.vo.ProductCategoryListReqVO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品分类 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProductCategoryMapper extends BaseMapperX<ProductCategoryDO> {
|
||||
|
||||
default List<ProductCategoryDO> selectList(ProductCategoryListReqVO listReqVO) {
|
||||
return selectList(new LambdaQueryWrapperX<ProductCategoryDO>()
|
||||
.likeIfPresent(ProductCategoryDO::getName, listReqVO.getName())
|
||||
.orderByDesc(ProductCategoryDO::getId));
|
||||
}
|
||||
|
||||
default Long selectCountByParentId(Long parentId) {
|
||||
return selectCount(ProductCategoryDO::getParentId, parentId);
|
||||
}
|
||||
|
||||
default List<ProductCategoryDO> selectListByStatus(Integer status) {
|
||||
return selectList(ProductCategoryDO::getStatus, status);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
package cn.iocoder.yudao.module.product.service.category;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.*;
|
||||
import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryListRespVO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
// TODO @JeromeSoar:需要 Product 前缀
|
||||
/**
|
||||
* 商品分类 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface CategoryService {
|
||||
|
||||
/**
|
||||
* 创建商品分类
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createCategory(@Valid CategoryCreateReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新商品分类
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateCategory(@Valid CategoryUpdateReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除商品分类
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteCategory(Long id);
|
||||
|
||||
/**
|
||||
* 获得商品分类
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 商品分类
|
||||
*/
|
||||
CategoryDO getCategory(Long id);
|
||||
|
||||
/**
|
||||
* 获得商品分类列表
|
||||
*
|
||||
* @param ids 编号
|
||||
* @return 商品分类列表
|
||||
*/
|
||||
List<CategoryDO> getCategoryList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得商品分类分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 商品分类分页
|
||||
*/
|
||||
PageResult<CategoryDO> getCategoryPage(CategoryPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得商品分类列表, 用于 Excel 导出
|
||||
*
|
||||
* @param exportReqVO 查询条件
|
||||
* @return 商品分类列表
|
||||
*/
|
||||
List<CategoryDO> getCategoryList(CategoryExportReqVO exportReqVO);
|
||||
|
||||
/**
|
||||
* 获得商品分类列表
|
||||
*
|
||||
* @param treeListReqVO 查询条件
|
||||
* @return 商品分类列表
|
||||
*/
|
||||
List<CategoryDO> getCategoryTreeList(CategoryTreeListReqVO treeListReqVO);
|
||||
|
||||
/**
|
||||
* 验证选择的分类的合法性
|
||||
* @param categoryId 分类id
|
||||
*/
|
||||
void validatedCategoryById(Long categoryId);
|
||||
|
||||
/**
|
||||
* app端获得商品分类列表
|
||||
*
|
||||
* @return 商品分类列表
|
||||
*/
|
||||
List<CategoryDO> getCategoryList();
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
package cn.iocoder.yudao.module.product.service.category;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.*;
|
||||
import cn.iocoder.yudao.module.product.convert.category.CategoryConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
|
||||
import cn.iocoder.yudao.module.product.dal.mysql.category.CategoryMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 商品分类 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class CategoryServiceImpl implements CategoryService {
|
||||
|
||||
@Resource
|
||||
private CategoryMapper categoryMapper;
|
||||
|
||||
@Override
|
||||
public Long createCategory(CategoryCreateReqVO createReqVO) {
|
||||
// 校验父分类存在
|
||||
this.validateCategoryExists(createReqVO.getParentId(), CATEGORY_PARENT_NOT_EXISTS);
|
||||
// 插入
|
||||
CategoryDO category = CategoryConvert.INSTANCE.convert(createReqVO);
|
||||
categoryMapper.insert(category);
|
||||
// 返回
|
||||
return category.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCategory(CategoryUpdateReqVO updateReqVO) {
|
||||
// 校验父分类存在
|
||||
this.validateCategoryExists(updateReqVO.getParentId(), CATEGORY_PARENT_NOT_EXISTS);
|
||||
// 校验分类是否存在
|
||||
this.validateCategoryExists(updateReqVO.getId(), CATEGORY_NOT_EXISTS);
|
||||
// 更新
|
||||
CategoryDO updateObj = CategoryConvert.INSTANCE.convert(updateReqVO);
|
||||
categoryMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCategory(Long id) {
|
||||
// TODO 芋艿 补充只有不存在商品才可以删除
|
||||
// 校验分类是否存在
|
||||
CategoryDO categoryDO = this.validateCategoryExists(id, CATEGORY_NOT_EXISTS);
|
||||
// 校验是否还有子分类
|
||||
if (categoryMapper.selectCountByParentId(categoryDO.getParentId()) > 0) {
|
||||
throw ServiceExceptionUtil.exception(CATEGORY_EXISTS_CHILDREN);
|
||||
}
|
||||
// 删除
|
||||
categoryMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private CategoryDO validateCategoryExists(Long id, ErrorCode errorCode) {
|
||||
// TODO franky:0 要枚举哈
|
||||
if (id == 0) {
|
||||
return new CategoryDO().setId(id);
|
||||
}
|
||||
CategoryDO categoryDO = categoryMapper.selectById(id);
|
||||
if (categoryDO == null) {
|
||||
throw exception(errorCode);
|
||||
}
|
||||
return categoryDO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validatedCategoryById(Long categoryId) {
|
||||
this.validateCategoryExists(categoryId, CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CategoryDO getCategory(Long id) {
|
||||
return categoryMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CategoryDO> getCategoryList(Collection<Long> ids) {
|
||||
return categoryMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<CategoryDO> getCategoryPage(CategoryPageReqVO pageReqVO) {
|
||||
return categoryMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CategoryDO> getCategoryList(CategoryExportReqVO exportReqVO) {
|
||||
return categoryMapper.selectList(exportReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CategoryDO> getCategoryTreeList(CategoryTreeListReqVO treeListReqVO) {
|
||||
return categoryMapper.selectList(treeListReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CategoryDO> getCategoryList() {
|
||||
return categoryMapper.selectList()
|
||||
.stream()
|
||||
.filter(v->v.getStatus().equals(CommonStatusEnum.ENABLE.getStatus()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package cn.iocoder.yudao.module.product.service.category;
|
||||
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品分类 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface ProductCategoryService {
|
||||
|
||||
/**
|
||||
* 创建商品分类
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createProductCategory(@Valid ProductCategoryCreateReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新商品分类
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateProductCategory(@Valid ProductCategoryUpdateReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除商品分类
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteProductCategory(Long id);
|
||||
|
||||
/**
|
||||
* 获得商品分类
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 商品分类
|
||||
*/
|
||||
ProductCategoryDO getProductCategory(Long id);
|
||||
|
||||
/**
|
||||
* 获得商品分类列表
|
||||
*
|
||||
* @param ids 编号
|
||||
* @return 商品分类列表
|
||||
*/
|
||||
List<ProductCategoryDO> getEnableProductCategoryList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得商品分类列表
|
||||
*
|
||||
* @param listReqVO 查询条件
|
||||
* @return 商品分类列表
|
||||
*/
|
||||
List<ProductCategoryDO> getEnableProductCategoryList(ProductCategoryListReqVO listReqVO);
|
||||
|
||||
/**
|
||||
* 验证选择的商品分类是否合法
|
||||
*
|
||||
* @param id 分类编号
|
||||
*/
|
||||
void validateProductCategory(Long id);
|
||||
|
||||
/**
|
||||
* 获得开启状态的商品分类列表
|
||||
*
|
||||
* @return 商品分类列表
|
||||
*/
|
||||
List<ProductCategoryDO> getEnableProductCategoryList();
|
||||
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
package cn.iocoder.yudao.module.product.service.category;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.convert.category.CategoryConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
|
||||
import cn.iocoder.yudao.module.product.dal.mysql.category.ProductCategoryMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 商品分类 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ProductCategoryServiceImpl implements ProductCategoryService {
|
||||
|
||||
@Resource
|
||||
private ProductCategoryMapper productCategoryMapper;
|
||||
|
||||
@Override
|
||||
public Long createProductCategory(ProductCategoryCreateReqVO createReqVO) {
|
||||
// 校验父分类存在
|
||||
validateParentProductCategory(createReqVO.getParentId());
|
||||
|
||||
// 插入
|
||||
ProductCategoryDO category = CategoryConvert.INSTANCE.convert(createReqVO);
|
||||
productCategoryMapper.insert(category);
|
||||
// 返回
|
||||
return category.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProductCategory(ProductCategoryUpdateReqVO updateReqVO) {
|
||||
// 校验分类是否存在
|
||||
validateProductCategoryExists(updateReqVO.getId());
|
||||
// 校验父分类存在
|
||||
validateParentProductCategory(updateReqVO.getParentId());
|
||||
|
||||
// 更新
|
||||
ProductCategoryDO updateObj = CategoryConvert.INSTANCE.convert(updateReqVO);
|
||||
productCategoryMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteProductCategory(Long id) {
|
||||
// 校验分类是否存在
|
||||
validateProductCategoryExists(id);
|
||||
// 校验是否还有子分类
|
||||
if (productCategoryMapper.selectCountByParentId(id) > 0) {
|
||||
throw exception(PRODUCT_CATEGORY_EXISTS_CHILDREN);
|
||||
}
|
||||
|
||||
// 删除
|
||||
productCategoryMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateParentProductCategory(Long id) {
|
||||
// 如果是根分类,无需验证
|
||||
if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) {
|
||||
return;
|
||||
}
|
||||
// 父分类不存在
|
||||
ProductCategoryDO category = productCategoryMapper.selectById(id);
|
||||
if (category == null) {
|
||||
throw exception(PRODUCT_CATEGORY_PARENT_NOT_EXISTS);
|
||||
}
|
||||
// 父分类不能是二级分类
|
||||
if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) {
|
||||
throw exception(PRODUCT_CATEGORY_PARENT_NOT_FIRST_LEVEL);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateProductCategoryExists(Long id) {
|
||||
ProductCategoryDO category = productCategoryMapper.selectById(id);
|
||||
if (category == null) {
|
||||
throw exception(PRODUCT_CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateProductCategory(Long id) {
|
||||
ProductCategoryDO category = productCategoryMapper.selectById(id);
|
||||
if (category == null) {
|
||||
throw exception(PRODUCT_CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
if (ObjectUtil.notEqual(category.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
|
||||
throw exception(PRODUCT_CATEGORY_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProductCategoryDO getProductCategory(Long id) {
|
||||
return productCategoryMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductCategoryDO> getEnableProductCategoryList(Collection<Long> ids) {
|
||||
return productCategoryMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductCategoryDO> getEnableProductCategoryList(ProductCategoryListReqVO listReqVO) {
|
||||
return productCategoryMapper.selectList(listReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductCategoryDO> getEnableProductCategoryList() {
|
||||
return productCategoryMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
}
|
||||
|
||||
}
|
|
@ -15,7 +15,7 @@ import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
|
|||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||
import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
|
||||
import cn.iocoder.yudao.module.product.service.category.CategoryService;
|
||||
import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
|
||||
import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
|
||||
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -42,7 +42,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||
private ProductSpuMapper ProductSpuMapper;
|
||||
|
||||
@Resource
|
||||
private CategoryService categoryService;
|
||||
private ProductCategoryService categoryService;
|
||||
|
||||
@Resource
|
||||
private ProductSkuService productSkuService;
|
||||
|
@ -54,7 +54,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||
@Transactional
|
||||
public Long createSpu(ProductSpuCreateReqVO createReqVO) {
|
||||
// 校验分类
|
||||
categoryService.validatedCategoryById(createReqVO.getCategoryId());
|
||||
categoryService.validateProductCategory(createReqVO.getCategoryId());
|
||||
// 校验SKU
|
||||
List<ProductSkuCreateReqVO> skuCreateReqList = createReqVO.getSkus();
|
||||
productSkuService.validateSkus(skuCreateReqList);
|
||||
|
@ -78,7 +78,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||
// 校验 spu 是否存在
|
||||
this.validateSpuExists(updateReqVO.getId());
|
||||
// 校验分类
|
||||
categoryService.validatedCategoryById(updateReqVO.getCategoryId());
|
||||
categoryService.validateProductCategory(updateReqVO.getCategoryId());
|
||||
// 校验SKU
|
||||
List<ProductSkuCreateReqVO> skuCreateReqList = updateReqVO.getSkus();
|
||||
productSkuService.validateSkus(skuCreateReqList);
|
||||
|
@ -142,7 +142,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||
Long parentId = spuVO.getCategoryId();
|
||||
categoryArray.addFirst(parentId);
|
||||
while (parentId != 0) {
|
||||
parentId = categoryService.getCategory(parentId).getParentId();
|
||||
parentId = categoryService.getProductCategory(parentId).getParentId();
|
||||
if (parentId > 0) {
|
||||
categoryArray.addFirst(parentId);
|
||||
}
|
||||
|
|
|
@ -1,192 +0,0 @@
|
|||
package cn.iocoder.yudao.module.product.service.category;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryCreateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryExportReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
|
||||
import cn.iocoder.yudao.module.product.dal.mysql.category.CategoryMapper;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link CategoryServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(CategoryServiceImpl.class)
|
||||
public class CategoryServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private CategoryServiceImpl categoryService;
|
||||
|
||||
@Resource
|
||||
private CategoryMapper categoryMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateCategory_success() {
|
||||
// 准备参数
|
||||
CategoryCreateReqVO reqVO = randomPojo(CategoryCreateReqVO.class);
|
||||
|
||||
// 调用
|
||||
Long categoryId = categoryService.createCategory(reqVO);
|
||||
// 断言
|
||||
assertNotNull(categoryId);
|
||||
// 校验记录的属性是否正确
|
||||
CategoryDO category = categoryMapper.selectById(categoryId);
|
||||
assertPojoEquals(reqVO, category);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCategory_success() {
|
||||
// mock 数据
|
||||
CategoryDO dbCategory = randomPojo(CategoryDO.class);
|
||||
categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
CategoryUpdateReqVO reqVO = randomPojo(CategoryUpdateReqVO.class, o -> {
|
||||
o.setId(dbCategory.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
categoryService.updateCategory(reqVO);
|
||||
// 校验是否更新正确
|
||||
CategoryDO category = categoryMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, category);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCategory_notExists() {
|
||||
// 准备参数
|
||||
CategoryUpdateReqVO reqVO = randomPojo(CategoryUpdateReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> categoryService.updateCategory(reqVO), CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteCategory_success() {
|
||||
// mock 数据
|
||||
CategoryDO dbCategory = randomPojo(CategoryDO.class);
|
||||
categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbCategory.getId();
|
||||
|
||||
// 调用
|
||||
categoryService.deleteCategory(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(categoryMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteCategory_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> categoryService.deleteCategory(id), CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGetCategoryPage() {
|
||||
// mock 数据
|
||||
CategoryDO dbCategory = randomPojo(CategoryDO.class, o -> { // 等会查询到
|
||||
o.setParentId(null);
|
||||
o.setName(null);
|
||||
o.setIcon(null);
|
||||
o.setBannerUrl(null);
|
||||
o.setSort(null);
|
||||
o.setDescription(null);
|
||||
o.setStatus(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
categoryMapper.insert(dbCategory);
|
||||
// 测试 pid 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setParentId(null)));
|
||||
// 测试 name 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName(null)));
|
||||
// 测试 icon 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setIcon(null)));
|
||||
// 测试 bannerUrl 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setBannerUrl(null)));
|
||||
// 测试 sort 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setSort(null)));
|
||||
// 测试 description 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setDescription(null)));
|
||||
// 测试 status 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setStatus(null)));
|
||||
// 测试 createTime 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCreateTime(null)));
|
||||
// 准备参数
|
||||
CategoryPageReqVO reqVO = new CategoryPageReqVO();
|
||||
reqVO.setName(null);
|
||||
reqVO.setStatus(null);
|
||||
reqVO.setCreateTime(null);
|
||||
|
||||
// 调用
|
||||
PageResult<CategoryDO> pageResult = categoryService.getCategoryPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbCategory, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGetCategoryList() {
|
||||
// mock 数据
|
||||
CategoryDO dbCategory = randomPojo(CategoryDO.class, o -> { // 等会查询到
|
||||
o.setParentId(null);
|
||||
o.setName(null);
|
||||
o.setIcon(null);
|
||||
o.setBannerUrl(null);
|
||||
o.setSort(null);
|
||||
o.setDescription(null);
|
||||
o.setStatus(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
categoryMapper.insert(dbCategory);
|
||||
// 测试 pid 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setParentId(null)));
|
||||
// 测试 name 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName(null)));
|
||||
// 测试 icon 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setIcon(null)));
|
||||
// 测试 bannerUrl 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setBannerUrl(null)));
|
||||
// 测试 sort 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setSort(null)));
|
||||
// 测试 description 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setDescription(null)));
|
||||
// 测试 status 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setStatus(null)));
|
||||
// 测试 createTime 不匹配
|
||||
categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCreateTime(null)));
|
||||
// 准备参数
|
||||
CategoryExportReqVO reqVO = new CategoryExportReqVO();
|
||||
reqVO.setName(null);
|
||||
reqVO.setStatus(null);
|
||||
reqVO.setCreateTime(null);
|
||||
|
||||
// 调用
|
||||
List<CategoryDO> list = categoryService.getCategoryList(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbCategory, list.get(0));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package cn.iocoder.yudao.module.product.service.category;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
|
||||
import cn.iocoder.yudao.module.product.dal.mysql.category.ProductCategoryMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_CATEGORY_NOT_EXISTS;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link ProductCategoryServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(ProductCategoryServiceImpl.class)
|
||||
public class ProductCategoryServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private ProductCategoryServiceImpl productCategoryService;
|
||||
|
||||
@Resource
|
||||
private ProductCategoryMapper productCategoryMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateCategory_success() {
|
||||
// 准备参数
|
||||
ProductCategoryCreateReqVO reqVO = randomPojo(ProductCategoryCreateReqVO.class);
|
||||
// mock 父类
|
||||
ProductCategoryDO parentProductCategory = randomPojo(ProductCategoryDO.class, o -> o.setId(reqVO.getParentId()));
|
||||
productCategoryMapper.insert(parentProductCategory);
|
||||
|
||||
// 调用
|
||||
Long categoryId = productCategoryService.createProductCategory(reqVO);
|
||||
// 断言
|
||||
assertNotNull(categoryId);
|
||||
// 校验记录的属性是否正确
|
||||
ProductCategoryDO category = productCategoryMapper.selectById(categoryId);
|
||||
assertPojoEquals(reqVO, category);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCategory_success() {
|
||||
// mock 数据
|
||||
ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class);
|
||||
productCategoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
ProductCategoryUpdateReqVO reqVO = randomPojo(ProductCategoryUpdateReqVO.class, o -> {
|
||||
o.setId(dbCategory.getId()); // 设置更新的 ID
|
||||
});
|
||||
// mock 父类
|
||||
ProductCategoryDO parentProductCategory = randomPojo(ProductCategoryDO.class, o -> o.setId(reqVO.getParentId()));
|
||||
productCategoryMapper.insert(parentProductCategory);
|
||||
|
||||
// 调用
|
||||
productCategoryService.updateProductCategory(reqVO);
|
||||
// 校验是否更新正确
|
||||
ProductCategoryDO category = productCategoryMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, category);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCategory_notExists() {
|
||||
// 准备参数
|
||||
ProductCategoryUpdateReqVO reqVO = randomPojo(ProductCategoryUpdateReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> productCategoryService.updateProductCategory(reqVO), PRODUCT_CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteCategory_success() {
|
||||
// mock 数据
|
||||
ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class);
|
||||
productCategoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbCategory.getId();
|
||||
|
||||
// 调用
|
||||
productCategoryService.deleteProductCategory(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(productCategoryMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteCategory_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> productCategoryService.deleteProductCategory(id), PRODUCT_CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCategoryList() {
|
||||
// mock 数据
|
||||
ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class, o -> { // 等会查询到
|
||||
o.setName("奥特曼");
|
||||
});
|
||||
productCategoryMapper.insert(dbCategory);
|
||||
// 测试 name 不匹配
|
||||
productCategoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName("奥特块")));
|
||||
// 准备参数
|
||||
ProductCategoryListReqVO reqVO = new ProductCategoryListReqVO();
|
||||
reqVO.setName("特曼");
|
||||
|
||||
// 调用
|
||||
List<ProductCategoryDO> list = productCategoryService.getEnableProductCategoryList(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbCategory, list.get(0));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
spring:
|
||||
main:
|
||||
lazy-initialization: true # 开启懒加载,加快速度
|
||||
banner-mode: off # 单元测试,禁用 Banner
|
||||
|
||||
--- #################### 数据库相关配置 ####################
|
||||
|
||||
spring:
|
||||
# 数据源配置项
|
||||
datasource:
|
||||
name: ruoyi-vue-pro
|
||||
url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写
|
||||
driver-class-name: org.h2.Driver
|
||||
username: sa
|
||||
password:
|
||||
druid:
|
||||
async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
|
||||
initial-size: 1 # 单元测试,配置为 1,提升启动速度
|
||||
sql:
|
||||
init:
|
||||
schema-locations: classpath:/sql/create_tables.sql
|
||||
|
||||
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
|
||||
redis:
|
||||
host: 127.0.0.1 # 地址
|
||||
port: 16379 # 端口(单元测试,使用 16379 端口)
|
||||
database: 0 # 数据库索引
|
||||
|
||||
mybatis-plus:
|
||||
lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
|
||||
type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject
|
||||
|
||||
--- #################### 定时任务相关配置 ####################
|
||||
|
||||
--- #################### 配置中心相关配置 ####################
|
||||
|
||||
--- #################### 服务保障相关配置 ####################
|
||||
|
||||
# Lock4j 配置项(单元测试,禁用 Lock4j)
|
||||
|
||||
# Resilience4j 配置项
|
||||
|
||||
--- #################### 监控相关配置 ####################
|
||||
|
||||
--- #################### 芋道相关配置 ####################
|
||||
|
||||
# 芋道配置项,设置当前项目所有自定义的配置
|
||||
yudao:
|
||||
info:
|
||||
base-package: cn.iocoder.yudao
|
|
@ -0,0 +1,4 @@
|
|||
<configuration>
|
||||
<!-- 引用 Spring Boot 的 logback 基础配置 -->
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
|
||||
</configuration>
|
|
@ -2,8 +2,7 @@ CREATE TABLE IF NOT EXISTS "product_category" (
|
|||
"id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"parent_id" bigint(20) NOT NULL,
|
||||
"name" varchar(255) NOT NULL,
|
||||
"icon" varchar(100),
|
||||
"banner_url" varchar(255) NOT NULL,
|
||||
"pic_url" varchar(255) NOT NULL,
|
||||
"sort" int(11) NOT NULL,
|
||||
"description" varchar(1024) NOT NULL,
|
||||
"status" tinyint(4) NOT NULL,
|
||||
|
@ -12,7 +11,6 @@ CREATE TABLE IF NOT EXISTS "product_category" (
|
|||
"updater" varchar(64) DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"tenant_id" bigint(20) NOT NULL,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '商品分类';
|
||||
|
||||
|
@ -29,6 +27,5 @@ CREATE TABLE IF NOT EXISTS "product_brand" (
|
|||
"updater" varchar(64) DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"tenant_id" bigint(20) NOT NULL,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '品牌';
|
||||
|
|
Loading…
Reference in New Issue