【CRM:优化产品以及产品分类】

This commit is contained in:
ZanGe丶 2023-12-03 21:33:01 +08:00
parent 1a93e3a110
commit d2e965fb02
35 changed files with 688 additions and 565 deletions

View File

@ -50,11 +50,18 @@ public interface ErrorCodeConstants {
ErrorCode CRM_PERMISSION_DELETE_SELF_PERMISSION_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_007, "删除数据权限失败,原因:不能删除负责人"); ErrorCode CRM_PERMISSION_DELETE_SELF_PERMISSION_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_007, "删除数据权限失败,原因:不能删除负责人");
// ========== 产品 1_020_008_000 ========== // ========== 产品 1_020_008_000 ==========
ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_020_008_000, "产品不存在"); ErrorCode CRM_PRODUCT_NOT_EXISTS = new ErrorCode(1_020_008_000, "产品不存在");
ErrorCode PRODUCT_NO_EXISTS = new ErrorCode(1_020_008_001, "产品编号已存在"); ErrorCode CRM_PRODUCT_NO_EXISTS = new ErrorCode(1_020_008_001, "产品编号已存在");
// ========== 产品分类 1_020_009_000 ========== // ========== 产品分类 1_020_009_000 ==========
ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_020_009_000, "产品分类不存在"); ErrorCode CRM_PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_020_009_000, "产品分类不存在");
ErrorCode CRM_PRODUCT_CATEGORY_EXISTS = new ErrorCode(1_020_009_001, "产品分类已存在");
ErrorCode CRM_PRODUCT_CATEGORY_USED = new ErrorCode(1_020_009_002, "产品分类已关联产品");
ErrorCode CRM_CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1_020_009_003, "父分类不存在");
ErrorCode CRM_CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1_020_009_004, "父分类不能是二级分类");
ErrorCode CRM_CATEGORY_EXISTS_CHILDREN = new ErrorCode(1_020_009_005, "存在子分类,无法删除");
// ========== 商机状态类型 1_020_010_000 ========== // ========== 商机状态类型 1_020_010_000 ==========
ErrorCode BUSINESS_STATUS_TYPE_NOT_EXISTS = new ErrorCode(1_020_010_000, "商机状态类型不存在"); ErrorCode BUSINESS_STATUS_TYPE_NOT_EXISTS = new ErrorCode(1_020_010_000, "商机状态类型不存在");

View File

@ -0,0 +1,44 @@
package cn.iocoder.yudao.module.crm.enums.product;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* @author ZanGe
* @create 2023-11-30 21:53
*/
@Getter
@AllArgsConstructor
public enum CrmProductStatusEnum implements IntArrayValuable {
DISABLE(0, "下架"),
ENABLE(1, "上架");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmProductStatusEnum::getStatus).toArray();
/**
* 状态
*/
private final Integer status;
/**
* 状态名
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
/**
* 判断是否处于上架状态
*
* @param status 状态
* @return 是否处于上架状态
*/
public static boolean isEnable(Integer status) {
return ENABLE.getStatus().equals(status);
}
}

View File

@ -1,53 +1,46 @@
package cn.iocoder.yudao.module.crm.controller.admin.productcategory; package cn.iocoder.yudao.module.crm.controller.admin.product;
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.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
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 cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryListReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryUpdateReqVO;
import cn.iocoder.yudao.module.crm.convert.product.CrmProductCategoryConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO;
import cn.iocoder.yudao.module.crm.service.product.CrmProductCategoryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
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; 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.crm.controller.admin.productcategory.vo.*;
import cn.iocoder.yudao.module.crm.dal.dataobject.productcategory.ProductCategoryDO;
import cn.iocoder.yudao.module.crm.convert.productcategory.ProductCategoryConvert;
import cn.iocoder.yudao.module.crm.service.productcategory.ProductCategoryService;
@Tag(name = "管理后台 - 产品分类") @Tag(name = "管理后台 - 产品分类")
@RestController @RestController
@RequestMapping("/crm/product-category") @RequestMapping("/crm/product-category")
@Validated @Validated
public class ProductCategoryController { public class CrmProductCategoryController {
@Resource @Resource
private ProductCategoryService productCategoryService; private CrmProductCategoryService productCategoryService;
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建产品分类") @Operation(summary = "创建产品分类")
@PreAuthorize("@ss.hasPermission('crm:product-category:create')") @PreAuthorize("@ss.hasPermission('crm:product-category:create')")
public CommonResult<Long> createProductCategory(@Valid @RequestBody ProductCategoryCreateReqVO createReqVO) { public CommonResult<Long> createProductCategory(@Valid @RequestBody CrmProductCategoryCreateReqVO createReqVO) {
return success(productCategoryService.createProductCategory(createReqVO)); return success(productCategoryService.createProductCategory(createReqVO));
} }
@PutMapping("/update") @PutMapping("/update")
@Operation(summary = "更新产品分类") @Operation(summary = "更新产品分类")
@PreAuthorize("@ss.hasPermission('crm:product-category:update')") @PreAuthorize("@ss.hasPermission('crm:product-category:update')")
public CommonResult<Boolean> updateProductCategory(@Valid @RequestBody ProductCategoryUpdateReqVO updateReqVO) { public CommonResult<Boolean> updateProductCategory(@Valid @RequestBody CrmProductCategoryUpdateReqVO updateReqVO) {
productCategoryService.updateProductCategory(updateReqVO); productCategoryService.updateProductCategory(updateReqVO);
return success(true); return success(true);
} }
@ -65,17 +58,17 @@ public class ProductCategoryController {
@Operation(summary = "获得产品分类") @Operation(summary = "获得产品分类")
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('crm:product-category:query')") @PreAuthorize("@ss.hasPermission('crm:product-category:query')")
public CommonResult<ProductCategoryRespVO> getProductCategory(@RequestParam("id") Long id) { public CommonResult<CrmProductCategoryRespVO> getProductCategory(@RequestParam("id") Long id) {
ProductCategoryDO productCategory = productCategoryService.getProductCategory(id); CrmProductCategoryDO productCategory = productCategoryService.getProductCategory(id);
return success(ProductCategoryConvert.INSTANCE.convert(productCategory)); return success(CrmProductCategoryConvert.INSTANCE.convert(productCategory));
} }
@GetMapping("/list") @GetMapping("/list")
@Operation(summary = "获得产品分类列表") @Operation(summary = "获得产品分类列表")
@PreAuthorize("@ss.hasPermission('crm:product-category:query')") @PreAuthorize("@ss.hasPermission('crm:product-category:query')")
public CommonResult<List<ProductCategoryRespVO>> getProductCategoryList(@Valid ProductCategoryListReqVO treeListReqVO) { public CommonResult<List<CrmProductCategoryRespVO>> getProductCategoryList(@Valid CrmProductCategoryListReqVO treeListReqVO) {
List<ProductCategoryDO> list = productCategoryService.getProductCategoryList(treeListReqVO); List<CrmProductCategoryDO> list = productCategoryService.getProductCategoryList(treeListReqVO);
return success(ProductCategoryConvert.INSTANCE.convertList(list)); return success(CrmProductCategoryConvert.INSTANCE.convertList(list));
} }
} }

View File

@ -4,10 +4,10 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.*; import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.*;
import cn.iocoder.yudao.module.crm.convert.product.ProductConvert; import cn.iocoder.yudao.module.crm.convert.product.CrmProductConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.ProductDO; import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
import cn.iocoder.yudao.module.crm.service.product.ProductService; import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
@ -28,22 +28,22 @@ import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.E
@RestController @RestController
@RequestMapping("/crm/product") @RequestMapping("/crm/product")
@Validated @Validated
public class ProductController { public class CrmProductController {
@Resource @Resource
private ProductService productService; private CrmProductService productService;
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建产品") @Operation(summary = "创建产品")
@PreAuthorize("@ss.hasPermission('crm:product:create')") @PreAuthorize("@ss.hasPermission('crm:product:create')")
public CommonResult<Long> createProduct(@Valid @RequestBody ProductCreateReqVO createReqVO) { public CommonResult<Long> createProduct(@Valid @RequestBody CrmProductCreateReqVO createReqVO) {
return success(productService.createProduct(createReqVO)); return success(productService.createProduct(createReqVO));
} }
@PutMapping("/update") @PutMapping("/update")
@Operation(summary = "更新产品") @Operation(summary = "更新产品")
@PreAuthorize("@ss.hasPermission('crm:product:update')") @PreAuthorize("@ss.hasPermission('crm:product:update')")
public CommonResult<Boolean> updateProduct(@Valid @RequestBody ProductUpdateReqVO updateReqVO) { public CommonResult<Boolean> updateProduct(@Valid @RequestBody CrmProductUpdateReqVO updateReqVO) {
productService.updateProduct(updateReqVO); productService.updateProduct(updateReqVO);
return success(true); return success(true);
} }
@ -61,29 +61,29 @@ public class ProductController {
@Operation(summary = "获得产品") @Operation(summary = "获得产品")
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('crm:product:query')") @PreAuthorize("@ss.hasPermission('crm:product:query')")
public CommonResult<ProductRespVO> getProduct(@RequestParam("id") Long id) { public CommonResult<CrmProductRespVO> getProduct(@RequestParam("id") Long id) {
ProductDO product = productService.getProduct(id); CrmProductDO product = productService.getProduct(id);
return success(ProductConvert.INSTANCE.convert(product)); return success(CrmProductConvert.INSTANCE.convert(product));
} }
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得产品分页") @Operation(summary = "获得产品分页")
@PreAuthorize("@ss.hasPermission('crm:product:query')") @PreAuthorize("@ss.hasPermission('crm:product:query')")
public CommonResult<PageResult<ProductRespVO>> getProductPage(@Valid ProductPageReqVO pageVO) { public CommonResult<PageResult<CrmProductRespVO>> getProductPage(@Valid CrmProductPageReqVO pageVO) {
PageResult<ProductDO> pageResult = productService.getProductPage(pageVO); PageResult<CrmProductDO> pageResult = productService.getProductPage(pageVO);
return success(ProductConvert.INSTANCE.convertPage(pageResult)); return success(CrmProductConvert.INSTANCE.convertPage(pageResult));
} }
@GetMapping("/export-excel") @GetMapping("/export-excel")
@Operation(summary = "导出产品 Excel") @Operation(summary = "导出产品 Excel")
@PreAuthorize("@ss.hasPermission('crm:product:export')") @PreAuthorize("@ss.hasPermission('crm:product:export')")
@OperateLog(type = EXPORT) @OperateLog(type = EXPORT)
public void exportProductExcel(@Valid ProductExportReqVO exportReqVO, public void exportProductExcel(@Valid CrmProductExportReqVO exportReqVO,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
List<ProductDO> list = productService.getProductList(exportReqVO); List<CrmProductDO> list = productService.getProductList(exportReqVO);
// 导出 Excel // 导出 Excel
List<ProductExcelVO> datas = ProductConvert.INSTANCE.convertList02(list); List<CrmProductExcelVO> datas = CrmProductConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "产品.xls", "数据", ProductExcelVO.class, datas); ExcelUtils.write(response, "产品.xls", "数据", CrmProductExcelVO.class, datas);
} }
} }

View File

@ -1,14 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.product.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 产品创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductCreateReqVO extends ProductBaseVO {
}

View File

@ -1,49 +1,45 @@
package cn.iocoder.yudao.module.crm.controller.admin.product.vo; package cn.iocoder.yudao.module.crm.controller.admin.product.vo.product;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
// TODO @zange需要加 CRM 前置噢 // TODO @zange-ok需要加 CRM 前置噢
/** /**
* 产品 Base VO提供给添加修改详细的子 VO 使用 * 产品 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成 * 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/ */
@Data @Data
public class ProductBaseVO { public class CrmProductBaseVO {
// TODO @zangeexample 要写哈主要是接口文档可以基于 example 可以生产请求参数 // TODO @zangeexample 要写哈主要是接口文档可以基于 example 可以生产请求参数
@Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "好产品")
@NotNull(message = "产品名称不能为空") @NotNull(message = "产品名称不能为空")
private String name; private String name;
@Schema(description = "产品编码", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "产品编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "12306")
@NotNull(message = "产品编码不能为空") @NotNull(message = "产品编码不能为空")
private String no; private String no;
@Schema(description = "单位") @Schema(description = "单位", example = "2")
private String unit; private String unit;
@Schema(description = "价格", example = "8911") @Schema(description = "价格", example = "8911")
private Long price; private Long price;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "上架")
@NotNull(message = "状态不能为空") @NotNull(message = "状态不能为空")
private Integer status; private Integer status;
@Schema(description = "产品分类ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1738") @Schema(description = "产品分类ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "产品分类ID不能为空") @NotNull(message = "产品分类ID不能为空")
private Long categoryId; private Long categoryId;
@Schema(description = "产品描述", example = "你说的对") @Schema(description = "产品描述", example = "你说的对")
private String description; private String description;
// TODO @zange这个字段只有 create 可以传递update 不传递所以放到 create resp // TODO @zange-ok这个字段只有 create 可以传递update 不传递所以放到 create resp
@Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31926")
@NotNull(message = "负责人的用户编号不能为空")
private Long ownerUserId;
} }

View File

@ -0,0 +1,16 @@
package cn.iocoder.yudao.module.crm.controller.admin.product.vo.product;
import lombok.*;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 产品创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CrmProductCreateReqVO extends CrmProductBaseVO {
@Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31926")
@NotNull(message = "负责人的用户编号不能为空")
private Long ownerUserId;
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.product.vo; package cn.iocoder.yudao.module.crm.controller.admin.product.vo.product;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
@ -7,14 +7,14 @@ import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
// TODO 芋艿这个导出最后搞 // TODO 芋艿这个导出最后搞 那暂时就放着不动了哈
/** /**
* 产品 Excel VO * 产品 Excel VO
* *
* @author ZanGe * @author ZanGe
*/ */
@Data @Data
public class ProductExcelVO { public class CrmProductExcelVO {
@ExcelProperty("主键id") @ExcelProperty("主键id")
private Long id; private Long id;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.product.vo; package cn.iocoder.yudao.module.crm.controller.admin.product.vo.product;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
@ -11,7 +11,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
// TODO 芋艿这个导出最后搞 // TODO 芋艿这个导出最后搞
@Schema(description = "管理后台 - 产品 Excel 导出 Request VO参数和 ProductPageReqVO 是一致的") @Schema(description = "管理后台 - 产品 Excel 导出 Request VO参数和 ProductPageReqVO 是一致的")
@Data @Data
public class ProductExportReqVO { public class CrmProductExportReqVO {
@Schema(description = "产品名称", example = "李四") @Schema(description = "产品名称", example = "李四")
private String name; private String name;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.product.vo; package cn.iocoder.yudao.module.crm.controller.admin.product.vo.product;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
@ -11,12 +11,12 @@ import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
// TODO @zange按照需求裁剪下筛选的字段目前应该只要 name status // TODO @zange-ok按照需求裁剪下筛选的字段目前应该只要 name status
@Schema(description = "管理后台 - 产品分页 Request VO") @Schema(description = "管理后台 - 产品分页 Request VO")
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
public class ProductPageReqVO extends PageParam { public class CrmProductPageReqVO extends PageParam {
@Schema(description = "产品名称", example = "李四") @Schema(description = "产品名称", example = "李四")
private String name; private String name;

View File

@ -1,14 +1,16 @@
package cn.iocoder.yudao.module.crm.controller.admin.product.vo; package cn.iocoder.yudao.module.crm.controller.admin.product.vo.product;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@Schema(description = "管理后台 - 产品 Response VO") @Schema(description = "管理后台 - 产品 Response VO")
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
public class ProductRespVO extends ProductBaseVO { public class CrmProductRespVO extends CrmProductBaseVO {
@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
private Long id; private Long id;
@ -16,4 +18,7 @@ public class ProductRespVO extends ProductBaseVO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime; private LocalDateTime createTime;
@Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31926")
@NotNull(message = "负责人的用户编号不能为空")
private Long ownerUserId;
} }

View File

@ -1,15 +1,15 @@
package cn.iocoder.yudao.module.crm.controller.admin.product.vo; package cn.iocoder.yudao.module.crm.controller.admin.product.vo.product;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import java.util.*;
import javax.validation.constraints.*; import javax.validation.constraints.*;
@Schema(description = "管理后台 - 产品更新 Request VO") @Schema(description = "管理后台 - 产品更新 Request VO")
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
public class ProductUpdateReqVO extends ProductBaseVO { public class CrmProductUpdateReqVO extends CrmProductBaseVO {
@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
@NotNull(message = "主键id不能为空") @NotNull(message = "主键id不能为空")

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.productcategory.vo; package cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
@ -10,7 +10,7 @@ import javax.validation.constraints.NotNull;
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成 * 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/ */
@Data @Data
public class ProductCategoryBaseVO { public class CrmProductCategoryBaseVO {
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
@NotNull(message = "名称不能为空") @NotNull(message = "名称不能为空")

View File

@ -1,14 +1,12 @@
package cn.iocoder.yudao.module.crm.controller.admin.productcategory.vo; package cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory;
import lombok.*; import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 产品分类创建 Request VO") @Schema(description = "管理后台 - 产品分类创建 Request VO")
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
public class ProductCategoryCreateReqVO extends ProductCategoryBaseVO { public class CrmProductCategoryCreateReqVO extends CrmProductCategoryBaseVO {
} }

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.productcategory.vo; package cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
@ -9,7 +9,7 @@ import java.time.LocalDateTime;
// TODO 芋艿这个导出最后搞命名应该是按照 ProductExportReqVO 风格 // TODO 芋艿这个导出最后搞命名应该是按照 ProductExportReqVO 风格
@Schema(description = "管理后台 - 产品分类列表 Request VO") @Schema(description = "管理后台 - 产品分类列表 Request VO")
@Data @Data
public class ProductCategoryListReqVO { public class CrmProductCategoryListReqVO {
@ExcelProperty("名称") @ExcelProperty("名称")
private String name; private String name;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.productcategory.vo; package cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
@ -8,7 +8,7 @@ import java.time.LocalDateTime;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
public class ProductCategoryRespVO extends ProductCategoryBaseVO { public class CrmProductCategoryRespVO extends CrmProductCategoryBaseVO {
@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "23902") @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "23902")
private Long id; private Long id;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.productcategory.vo; package cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
@ -11,7 +11,7 @@ import javax.validation.constraints.NotNull;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO { public class CrmProductCategoryUpdateReqVO extends CrmProductCategoryBaseVO {
@Schema(description = "主键 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "23902") @Schema(description = "主键 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "23902")
@NotNull(message = "主键 id 不能为空") @NotNull(message = "主键 id 不能为空")

View File

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.crm.convert.product;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryUpdateReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 产品分类 Convert
*
* @author ZanGe
*/
@Mapper
public interface CrmProductCategoryConvert {
CrmProductCategoryConvert INSTANCE = Mappers.getMapper(CrmProductCategoryConvert.class);
CrmProductCategoryDO convert(CrmProductCategoryCreateReqVO bean);
CrmProductCategoryDO convert(CrmProductCategoryUpdateReqVO bean);
CrmProductCategoryRespVO convert(CrmProductCategoryDO bean);
List<CrmProductCategoryRespVO> convertList(List<CrmProductCategoryDO> list);
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.crm.convert.product;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductExcelVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductUpdateReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 产品 Convert
*
* @author ZanGe
*/
@Mapper
public interface CrmProductConvert {
CrmProductConvert INSTANCE = Mappers.getMapper(CrmProductConvert.class);
CrmProductDO convert(CrmProductCreateReqVO bean);
CrmProductDO convert(CrmProductUpdateReqVO bean);
CrmProductRespVO convert(CrmProductDO bean);
List<CrmProductRespVO> convertList(List<CrmProductDO> list);
PageResult<CrmProductRespVO> convertPage(PageResult<CrmProductDO> page);
List<CrmProductExcelVO> convertList02(List<CrmProductDO> list);
}

View File

@ -1,34 +0,0 @@
package cn.iocoder.yudao.module.crm.convert.product;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.*;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.ProductDO;
/**
* 产品 Convert
*
* @author ZanGe
*/
@Mapper
public interface ProductConvert {
ProductConvert INSTANCE = Mappers.getMapper(ProductConvert.class);
ProductDO convert(ProductCreateReqVO bean);
ProductDO convert(ProductUpdateReqVO bean);
ProductRespVO convert(ProductDO bean);
List<ProductRespVO> convertList(List<ProductDO> list);
PageResult<ProductRespVO> convertPage(PageResult<ProductDO> page);
List<ProductExcelVO> convertList02(List<ProductDO> list);
}

View File

@ -1,30 +0,0 @@
package cn.iocoder.yudao.module.crm.convert.productcategory;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.module.crm.controller.admin.productcategory.vo.*;
import cn.iocoder.yudao.module.crm.dal.dataobject.productcategory.ProductCategoryDO;
/**
* 产品分类 Convert
*
* @author ZanGe
*/
@Mapper
public interface ProductCategoryConvert {
ProductCategoryConvert INSTANCE = Mappers.getMapper(ProductCategoryConvert.class);
ProductCategoryDO convert(ProductCategoryCreateReqVO bean);
ProductCategoryDO convert(ProductCategoryUpdateReqVO bean);
ProductCategoryRespVO convert(ProductCategoryDO bean);
List<ProductCategoryRespVO> convertList(List<ProductCategoryDO> list);
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.dal.dataobject.productcategory; package cn.iocoder.yudao.module.crm.dal.dataobject.product;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.KeySequence;
@ -19,7 +19,16 @@ import lombok.*;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class ProductCategoryDO extends BaseDO { public class CrmProductCategoryDO extends BaseDO {
/**
* 父分类编号 - 根分类
*/
public static final Long PARENT_ID_NULL = 0L;
/**
* 限定分类层级
*/
public static final int CATEGORY_LEVEL = 2;
/** /**
* 主键id * 主键id
@ -32,7 +41,7 @@ public class ProductCategoryDO extends BaseDO {
private String name; private String name;
/** /**
* 父级 id * 父级 id
* // TODO @zange这个要写下关联 CategoryDO id 字段参考下别的模块哈 * // TODO @zange-ok这个要写下关联 CategoryDO id 字段参考下别的模块哈
*/ */
private Long parentId; private Long parentId;

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.crm.dal.dataobject.product; package cn.iocoder.yudao.module.crm.dal.dataobject.product;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.crm.enums.product.CrmProductStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
@ -19,7 +20,7 @@ import lombok.*;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class ProductDO extends BaseDO { public class CrmProductDO extends BaseDO {
/** /**
* 主键 id * 主键 id
@ -44,14 +45,12 @@ public class ProductDO extends BaseDO {
private Long price; private Long price;
/** /**
* 状态 * 状态
* * 关联 {@link CrmProductStatusEnum}
* 枚举 {@link TODO crm_product_status 对应的类}
* // TODO @zange这个写个枚举类然后 {@link关联下
*/ */
private Integer status; private Integer status;
/** /**
* 产品分类 ID * 产品分类 ID
* // TODO @zange这个要写下关联 CategoryDO id 字段参考下别的模块哈 * 关联 {@link CrmProductCategoryDO#id}
*/ */
private Long categoryId; private Long categoryId;
/** /**

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.crm.dal.mysql.product;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryListReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 产品分类 Mapper
*
* @author ZanGe
*/
@Mapper
public interface CrmProductCategoryMapper extends BaseMapperX<CrmProductCategoryDO> {
default List<CrmProductCategoryDO> selectList(CrmProductCategoryListReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<CrmProductCategoryDO>()
.likeIfPresent(CrmProductCategoryDO::getName, reqVO.getName())
.eqIfPresent(CrmProductCategoryDO::getParentId, reqVO.getParentId())
.orderByDesc(CrmProductCategoryDO::getId));
}
default CrmProductCategoryDO selectByName(String name) {
return selectOne(CrmProductCategoryDO::getName, name);
}
default Long selectCountByParentId(Long parentId) {
return selectCount(CrmProductCategoryDO::getParentId, parentId);
}
}

View File

@ -0,0 +1,38 @@
package cn.iocoder.yudao.module.crm.dal.mysql.product;
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.crm.controller.admin.product.vo.product.CrmProductExportReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 产品 Mapper
*
* @author ZanGe
*/
@Mapper
public interface CrmProductMapper extends BaseMapperX<CrmProductDO> {
default PageResult<CrmProductDO> selectPage(CrmProductPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<CrmProductDO>()
.likeIfPresent(CrmProductDO::getName, reqVO.getName())
.eqIfPresent(CrmProductDO::getStatus, reqVO.getStatus())
.orderByDesc(CrmProductDO::getId));
}
default List<CrmProductDO> selectList(CrmProductExportReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<CrmProductDO>()
.likeIfPresent(CrmProductDO::getName, reqVO.getName())
.eqIfPresent(CrmProductDO::getStatus, reqVO.getStatus())
.orderByDesc(CrmProductDO::getId));
}
default CrmProductDO selectByNo(String no) {
return selectOne(CrmProductDO::getNo, no);
}
}

View File

@ -1,48 +0,0 @@
package cn.iocoder.yudao.module.crm.dal.mysql.product;
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.crm.dal.dataobject.product.ProductDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.*;
/**
* 产品 Mapper
*
* @author ZanGe
*/
@Mapper
public interface ProductMapper extends BaseMapperX<ProductDO> {
default PageResult<ProductDO> selectPage(ProductPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ProductDO>()
.likeIfPresent(ProductDO::getName, reqVO.getName())
.likeIfPresent(ProductDO::getNo, reqVO.getNo())
.eqIfPresent(ProductDO::getUnit, reqVO.getUnit())
.eqIfPresent(ProductDO::getPrice, reqVO.getPrice())
.eqIfPresent(ProductDO::getStatus, reqVO.getStatus())
.eqIfPresent(ProductDO::getCategoryId, reqVO.getCategoryId())
.eqIfPresent(ProductDO::getDescription, reqVO.getDescription())
.eqIfPresent(ProductDO::getOwnerUserId, reqVO.getOwnerUserId())
.betweenIfPresent(ProductDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ProductDO::getId));
}
default List<ProductDO> selectList(ProductExportReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<ProductDO>()
.likeIfPresent(ProductDO::getName, reqVO.getName())
.likeIfPresent(ProductDO::getNo, reqVO.getNo())
.eqIfPresent(ProductDO::getUnit, reqVO.getUnit())
.eqIfPresent(ProductDO::getPrice, reqVO.getPrice())
.eqIfPresent(ProductDO::getStatus, reqVO.getStatus())
.eqIfPresent(ProductDO::getCategoryId, reqVO.getCategoryId())
.eqIfPresent(ProductDO::getDescription, reqVO.getDescription())
.eqIfPresent(ProductDO::getOwnerUserId, reqVO.getOwnerUserId())
.betweenIfPresent(ProductDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ProductDO::getId));
}
}

View File

@ -1,28 +0,0 @@
package cn.iocoder.yudao.module.crm.dal.mysql.productcategory;
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.crm.dal.dataobject.productcategory.ProductCategoryDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.crm.controller.admin.productcategory.vo.*;
/**
* 产品分类 Mapper
*
* @author ZanGe
*/
@Mapper
public interface ProductCategoryMapper extends BaseMapperX<ProductCategoryDO> {
default List<ProductCategoryDO> selectList(ProductCategoryListReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<ProductCategoryDO>()
.likeIfPresent(ProductCategoryDO::getName, reqVO.getName())
.eqIfPresent(ProductCategoryDO::getParentId, reqVO.getParentId())
.orderByDesc(ProductCategoryDO::getId));
}
}

View File

@ -0,0 +1,56 @@
package cn.iocoder.yudao.module.crm.service.product;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryListReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryUpdateReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO;
import javax.validation.Valid;
import java.util.List;
/**
* 产品分类 Service 接口
*
* @author ZanGe
*/
public interface CrmProductCategoryService {
/**
* 创建产品分类
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createProductCategory(@Valid CrmProductCategoryCreateReqVO createReqVO);
/**
* 更新产品分类
*
* @param updateReqVO 更新信息
*/
void updateProductCategory(@Valid CrmProductCategoryUpdateReqVO updateReqVO);
/**
* 删除产品分类
*
* @param id 编号
*/
void deleteProductCategory(Long id);
/**
* 获得产品分类
*
* @param id 编号
* @return 产品分类
*/
CrmProductCategoryDO getProductCategory(Long id);
/**
* 获得产品分类列表
*
* @param ids 编号
* @return 产品分类列表
*/
List<CrmProductCategoryDO> getProductCategoryList(CrmProductCategoryListReqVO treeListReqVO);
}

View File

@ -0,0 +1,122 @@
package cn.iocoder.yudao.module.crm.service.product;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryListReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.productcategory.CrmProductCategoryUpdateReqVO;
import cn.iocoder.yudao.module.crm.convert.product.CrmProductCategoryConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO;
import cn.iocoder.yudao.module.crm.dal.mysql.product.CrmProductCategoryMapper;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
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.crm.dal.dataobject.product.CrmProductCategoryDO.PARENT_ID_NULL;
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
// TODO @zange-ok这个类所在的包放到 product
/**
* 产品分类 Service 实现类
*
* @author ZanGe
*/
@Service
@Validated
public class CrmProductCategoryServiceImpl implements CrmProductCategoryService {
@Resource
private CrmProductCategoryMapper productCategoryMapper;
@Resource
@Lazy
private CrmProductService crmProductService;
@Override
public Long createProductCategory(CrmProductCategoryCreateReqVO createReqVO) {
// TODO zange参考 mall ProductCategoryServiceImpl 补充下必要的参数校验
// 校验父分类存在
validateParentProductCategory(createReqVO.getParentId());
// 分类名称是否存在
CrmProductCategoryDO dbProductCategory = productCategoryMapper.selectByName(createReqVO.getName());
if (dbProductCategory != null) {
return dbProductCategory.getId();
}
// 插入
CrmProductCategoryDO productCategory = CrmProductCategoryConvert.INSTANCE.convert(createReqVO);
productCategoryMapper.insert(productCategory);
// 返回
return productCategory.getId();
}
@Override
public void updateProductCategory(CrmProductCategoryUpdateReqVO updateReqVO) {
// TODO zange参考 mall ProductCategoryServiceImpl 补充下必要的参数校验
// 校验存在
validateProductCategoryExists(updateReqVO.getId());
// 校验父分类存在
validateParentProductCategory(updateReqVO.getParentId());
// 校验名字重复
CrmProductCategoryDO productCategoryDO = productCategoryMapper.selectByName(updateReqVO.getName());
if (productCategoryDO != null &&
ObjUtil.notEqual(productCategoryDO.getId(), updateReqVO.getId())) {
throw exception(CRM_PRODUCT_CATEGORY_EXISTS);
}
// 更新
CrmProductCategoryDO updateObj = CrmProductCategoryConvert.INSTANCE.convert(updateReqVO);
productCategoryMapper.updateById(updateObj);
}
@Override
public void deleteProductCategory(Long id) {
// TODO zange参考 mall ProductCategoryServiceImpl 补充下必要的参数校验
// 校验存在
validateProductCategoryExists(id);
// 校验是否还有子分类
if (productCategoryMapper.selectCountByParentId(id) > 0) {
throw exception(CRM_CATEGORY_EXISTS_CHILDREN);
}
// 校验是否被产品使用
if (crmProductService.getProductByCategoryId(id) !=null) {
throw exception(CRM_PRODUCT_CATEGORY_USED);
}
// 删除
productCategoryMapper.deleteById(id);
}
private void validateProductCategoryExists(Long id) {
if (productCategoryMapper.selectById(id) == null) {
throw exception(CRM_PRODUCT_CATEGORY_NOT_EXISTS);
}
}
private void validateParentProductCategory(Long id) {
// 如果是根分类无需验证
if (Objects.equals(id, PARENT_ID_NULL)) {
return;
}
// 父分类不存在
CrmProductCategoryDO category = productCategoryMapper.selectById(id);
if (category == null) {
throw exception(CRM_CATEGORY_PARENT_NOT_EXISTS);
}
// 父分类不能是二级分类
if (!Objects.equals(category.getParentId(), PARENT_ID_NULL)) {
throw exception(CRM_CATEGORY_PARENT_NOT_FIRST_LEVEL);
}
}
@Override
public CrmProductCategoryDO getProductCategory(Long id) {
return productCategoryMapper.selectById(id);
}
@Override
public List<CrmProductCategoryDO> getProductCategoryList(CrmProductCategoryListReqVO treeListReqVO) {
return productCategoryMapper.selectList(treeListReqVO);
}
}

View File

@ -0,0 +1,82 @@
package cn.iocoder.yudao.module.crm.service.product;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductExportReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductUpdateReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
/**
* 产品 Service 接口
*
* @author ZanGe
*/
public interface CrmProductService {
/**
* 创建产品
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createProduct(@Valid CrmProductCreateReqVO createReqVO);
/**
* 更新产品
*
* @param updateReqVO 更新信息
*/
void updateProduct(@Valid CrmProductUpdateReqVO updateReqVO);
/**
* 删除产品
*
* @param id 编号
*/
void deleteProduct(Long id);
/**
* 获得产品
*
* @param id 编号
* @return 产品
*/
CrmProductDO getProduct(Long id);
/**
* 获得产品列表
*
* @param ids 编号
* @return 产品列表
*/
List<CrmProductDO> getProductList(Collection<Long> ids);
/**
* 获得产品分页
*
* @param pageReqVO 分页查询
* @return 产品分页
*/
PageResult<CrmProductDO> getProductPage(CrmProductPageReqVO pageReqVO);
/**
* 获得产品列表, 用于 Excel 导出
*
* @param exportReqVO 查询条件
* @return 产品列表
*/
List<CrmProductDO> getProductList(CrmProductExportReqVO exportReqVO);
/**
* 获得产品
*
* @param categoryId 分类编号
* @return 产品
*/
CrmProductDO getProductByCategoryId(Long categoryId);
}

View File

@ -0,0 +1,121 @@
package cn.iocoder.yudao.module.crm.service.product;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductExportReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductUpdateReqVO;
import cn.iocoder.yudao.module.crm.convert.product.CrmProductConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
import cn.iocoder.yudao.module.crm.dal.mysql.product.CrmProductMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
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.crm.enums.ErrorCodeConstants.*;
/**
* 产品 Service 实现类
*
* @author ZanGe
*/
@Service
@Validated
public class CrmProductServiceImpl implements CrmProductService {
@Resource
private CrmProductMapper productMapper;
@Resource
private CrmProductCategoryService productCategoryService;
@Override
public Long createProduct(CrmProductCreateReqVO createReqVO) {
// 校验产品编号是否存在
validateProductNoDuplicate(createReqVO.getNo());
// TODO @zange-ok需要校验 categoryId 是否存在
validateProductCategoryExists(createReqVO.getCategoryId());
// 插入
CrmProductDO product = CrmProductConvert.INSTANCE.convert(createReqVO);
productMapper.insert(product);
// 返回
return product.getId();
}
@Override
public void updateProduct(CrmProductUpdateReqVO updateReqVO) {
// 校验存在
validateProductExists(updateReqVO.getId());
// TODO @zange-ok需要校验 categoryId 是否存在
validateProductCategoryExists(updateReqVO.getCategoryId());
// 更新
CrmProductDO updateObj = CrmProductConvert.INSTANCE.convert(updateReqVO);
productMapper.updateById(updateObj);
}
@Override
public void deleteProduct(Long id) {
// 校验存在
validateProductExists(id);
// 删除
productMapper.deleteById(id);
}
// TODO @zange-okvalidateProductExists 要不只校验是否存在然后是否 no 重复交给 validateProductNo名字改成 validateProductNoDuplicate和别的模块保持一致哈
private void validateProductExists(Long id) {
CrmProductDO product = productMapper.selectById(id);
if (product == null) {
throw exception(CRM_PRODUCT_NOT_EXISTS);
}
}
private void validateProductCategoryExists(Long categoryId) {
CrmProductCategoryDO productCategory = productCategoryService.getProductCategory(categoryId);
if (productCategory == null) {
throw exception(CRM_PRODUCT_CATEGORY_NOT_EXISTS);
}
}
@Override
public CrmProductDO getProduct(Long id) {
return productMapper.selectById(id);
}
@Override
public List<CrmProductDO> getProductList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return ListUtil.empty();
}
return productMapper.selectBatchIds(ids);
}
@Override
public PageResult<CrmProductDO> getProductPage(CrmProductPageReqVO pageReqVO) {
return productMapper.selectPage(pageReqVO);
}
@Override
public List<CrmProductDO> getProductList(CrmProductExportReqVO exportReqVO) {
return productMapper.selectList(exportReqVO);
}
@Override
public CrmProductDO getProductByCategoryId(Long categoryId) {
return productMapper.selectOne(new LambdaQueryWrapper<CrmProductDO>().eq(CrmProductDO::getCategoryId, categoryId));
}
private void validateProductNoDuplicate(String no) {
CrmProductDO product = productMapper.selectOne(new LambdaQueryWrapper<CrmProductDO>().eq(CrmProductDO::getNo, no));
if (product != null) {
throw exception(CRM_PRODUCT_NO_EXISTS);
}
}
}

View File

@ -1,70 +0,0 @@
package cn.iocoder.yudao.module.crm.service.product;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.*;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.ProductDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* 产品 Service 接口
*
* @author ZanGe
*/
public interface ProductService {
/**
* 创建产品
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createProduct(@Valid ProductCreateReqVO createReqVO);
/**
* 更新产品
*
* @param updateReqVO 更新信息
*/
void updateProduct(@Valid ProductUpdateReqVO updateReqVO);
/**
* 删除产品
*
* @param id 编号
*/
void deleteProduct(Long id);
/**
* 获得产品
*
* @param id 编号
* @return 产品
*/
ProductDO getProduct(Long id);
/**
* 获得产品列表
*
* @param ids 编号
* @return 产品列表
*/
List<ProductDO> getProductList(Collection<Long> ids);
/**
* 获得产品分页
*
* @param pageReqVO 分页查询
* @return 产品分页
*/
PageResult<ProductDO> getProductPage(ProductPageReqVO pageReqVO);
/**
* 获得产品列表, 用于 Excel 导出
*
* @param exportReqVO 查询条件
* @return 产品列表
*/
List<ProductDO> getProductList(ProductExportReqVO exportReqVO);
}

View File

@ -1,108 +0,0 @@
package cn.iocoder.yudao.module.crm.service.product;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.ProductCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.ProductExportReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.ProductPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.ProductUpdateReqVO;
import cn.iocoder.yudao.module.crm.convert.product.ProductConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.ProductDO;
import cn.iocoder.yudao.module.crm.dal.mysql.product.ProductMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
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.crm.enums.ErrorCodeConstants.PRODUCT_NOT_EXISTS;
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.PRODUCT_NO_EXISTS;
/**
* 产品 Service 实现类
*
* @author ZanGe
*/
@Service
@Validated
public class ProductServiceImpl implements ProductService {
@Resource
private ProductMapper productMapper;
@Override
public Long createProduct(ProductCreateReqVO createReqVO) {
// 校验产品编号是否存在
validateProductNo(createReqVO.getNo());
// TODO @zange需要校验 categoryId 是否存在
// 插入
ProductDO product = ProductConvert.INSTANCE.convert(createReqVO);
productMapper.insert(product);
// 返回
return product.getId();
}
@Override
public void updateProduct(ProductUpdateReqVO updateReqVO) {
// 校验存在
validateProductExists(updateReqVO.getId(), updateReqVO.getNo());
// TODO @zange需要校验 categoryId 是否存在
// 更新
ProductDO updateObj = ProductConvert.INSTANCE.convert(updateReqVO);
productMapper.updateById(updateObj);
}
@Override
public void deleteProduct(Long id) {
// 校验存在
validateProductExists(id, null);
// 删除
productMapper.deleteById(id);
}
// TODO @zangevalidateProductExists 要不只校验是否存在然后是否 no 重复交给 validateProductNo名字改成 validateProductNoDuplicate和别的模块保持一致哈
private void validateProductExists(Long id, String no) {
ProductDO product = productMapper.selectById(id);
if (product == null) {
throw exception(PRODUCT_NOT_EXISTS);
}
if (no != null && no.equals(product.getNo())) {
throw exception(PRODUCT_NO_EXISTS);
}
}
@Override
public ProductDO getProduct(Long id) {
return productMapper.selectById(id);
}
@Override
public List<ProductDO> getProductList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return ListUtil.empty();
}
return productMapper.selectBatchIds(ids);
}
@Override
public PageResult<ProductDO> getProductPage(ProductPageReqVO pageReqVO) {
return productMapper.selectPage(pageReqVO);
}
@Override
public List<ProductDO> getProductList(ProductExportReqVO exportReqVO) {
return productMapper.selectList(exportReqVO);
}
private void validateProductNo(String no) {
ProductDO product = productMapper.selectOne(new LambdaQueryWrapper<ProductDO>().eq(ProductDO::getNo, no));
if (product != null) {
throw exception(PRODUCT_NO_EXISTS);
}
}
}

View File

@ -1,54 +0,0 @@
package cn.iocoder.yudao.module.crm.service.productcategory;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.crm.controller.admin.productcategory.vo.*;
import cn.iocoder.yudao.module.crm.dal.dataobject.productcategory.ProductCategoryDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* 产品分类 Service 接口
*
* @author ZanGe
*/
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> getProductCategoryList(ProductCategoryListReqVO treeListReqVO);
}

View File

@ -1,76 +0,0 @@
package cn.iocoder.yudao.module.crm.service.productcategory;
import cn.iocoder.yudao.module.crm.controller.admin.productcategory.vo.ProductCategoryCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.productcategory.vo.ProductCategoryListReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.productcategory.vo.ProductCategoryUpdateReqVO;
import cn.iocoder.yudao.module.crm.convert.productcategory.ProductCategoryConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.productcategory.ProductCategoryDO;
import cn.iocoder.yudao.module.crm.dal.mysql.productcategory.ProductCategoryMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.PRODUCT_CATEGORY_NOT_EXISTS;
// TODO @zange这个类所在的包放到 product
/**
* 产品分类 Service 实现类
*
* @author ZanGe
*/
@Service
@Validated
public class ProductCategoryServiceImpl implements ProductCategoryService {
@Resource
private ProductCategoryMapper productCategoryMapper;
@Override
public Long createProductCategory(ProductCategoryCreateReqVO createReqVO) {
// TODO zange参考 mall ProductCategoryServiceImpl 补充下必要的参数校验
// 插入
ProductCategoryDO productCategory = ProductCategoryConvert.INSTANCE.convert(createReqVO);
productCategoryMapper.insert(productCategory);
// 返回
return productCategory.getId();
}
@Override
public void updateProductCategory(ProductCategoryUpdateReqVO updateReqVO) {
// TODO zange参考 mall ProductCategoryServiceImpl 补充下必要的参数校验
// 校验存在
validateProductCategoryExists(updateReqVO.getId());
// 更新
ProductCategoryDO updateObj = ProductCategoryConvert.INSTANCE.convert(updateReqVO);
productCategoryMapper.updateById(updateObj);
}
@Override
public void deleteProductCategory(Long id) {
// TODO zange参考 mall ProductCategoryServiceImpl 补充下必要的参数校验
// 校验存在
validateProductCategoryExists(id);
// 删除
productCategoryMapper.deleteById(id);
}
private void validateProductCategoryExists(Long id) {
if (productCategoryMapper.selectById(id) == null) {
throw exception(PRODUCT_CATEGORY_NOT_EXISTS);
}
}
@Override
public ProductCategoryDO getProductCategory(Long id) {
return productCategoryMapper.selectById(id);
}
@Override
public List<ProductCategoryDO> getProductCategoryList(ProductCategoryListReqVO treeListReqVO) {
return productCategoryMapper.selectList(treeListReqVO);
}
}