From c1b4f066708669d37a9a05e9eeb7657b20f56c72 Mon Sep 17 00:00:00 2001 From: Tankaikai Date: Thu, 13 Feb 2025 18:52:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=95=86=E5=93=81=E6=A8=A1=E5=9D=97=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ShopProdCategoryController.java | 79 ++++++---- .../controller/ShopProdUnitController.java | 6 +- .../controller/ShopProductSpecController.java | 100 ++++++++++++ .../czg/product/dto/ShopProdCategoryDTO.java | 35 ++++- .../com/czg/product/dto/ShopProdUnitDTO.java | 2 +- .../czg/product/dto/ShopProductSpecDTO.java | 77 ++++++++++ .../czg/product/entity/ShopProdCategory.java | 20 ++- .../czg/product/entity/ShopProductSpec.java | 63 ++++++++ .../service/ShopProdCategoryService.java | 20 +++ .../service/ShopProductSpecService.java | 33 ++++ .../java/com/czg/constant/GlobalConstant.java | 18 +++ .../src/main/java/com/czg/utils/TreeNode.java | 35 +++++ .../main/java/com/czg/utils/TreeUtils.java | 72 +++++++++ .../product/mapper/ShopProductSpecMapper.java | 16 ++ .../impl/ShopProdCategoryServiceImpl.java | 97 ++++++++++++ .../impl/ShopProductSpecServiceImpl.java | 145 ++++++++++++++++++ 16 files changed, 764 insertions(+), 54 deletions(-) create mode 100644 cash-api/product-server/src/main/java/com/czg/controller/ShopProductSpecController.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProductSpecDTO.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProductSpec.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopProductSpecService.java create mode 100644 cash-common/cash-common-tools/src/main/java/com/czg/constant/GlobalConstant.java create mode 100644 cash-common/cash-common-tools/src/main/java/com/czg/utils/TreeNode.java create mode 100644 cash-common/cash-common-tools/src/main/java/com/czg/utils/TreeUtils.java create mode 100644 cash-service/product-service/src/main/java/com/czg/service/product/mapper/ShopProductSpecMapper.java create mode 100644 cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ShopProductSpecServiceImpl.java diff --git a/cash-api/product-server/src/main/java/com/czg/controller/ShopProdCategoryController.java b/cash-api/product-server/src/main/java/com/czg/controller/ShopProdCategoryController.java index 9fcb6c3c..4f1d5c6e 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/ShopProdCategoryController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/ShopProdCategoryController.java @@ -1,8 +1,5 @@ package com.czg.controller; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.lang.Validator; -import com.czg.annotation.SaAdminCheckPermission; import com.czg.log.annotation.OperationLog; import com.czg.product.dto.ShopProdCategoryDTO; import com.czg.product.service.ShopProdCategoryService; @@ -17,7 +14,6 @@ import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.*; import java.util.List; -import java.util.Map; /** @@ -33,67 +29,82 @@ public class ShopProdCategoryController { private final ShopProdCategoryService shopProdCategoryService; @GetMapping("page") - @OperationLog("分页") - @SaAdminCheckPermission("prod:category:all") - public CzgResult> page(@RequestParam Map params) { - Page data = shopProdCategoryService.pageAs(null, null, ShopProdCategoryDTO.class); + @OperationLog("商品分类-分页") + //@SaAdminCheckPermission("prod:category:page") + public CzgResult> page(ShopProdCategoryDTO param) { + Page data = shopProdCategoryService.page(param); return CzgResult.success(data); } @GetMapping("list") - @OperationLog("列表") - @SaAdminCheckPermission("prod:category:all") - public CzgResult> list(@RequestParam Map params) { - List data = null; - + @OperationLog("商品分类-列表") + //@SaAdminCheckPermission("prod:category:list") + public CzgResult> list(ShopProdCategoryDTO param) { + List data = shopProdCategoryService.list(param); return CzgResult.success(data); } @GetMapping("{id}") - @OperationLog("信息") - @SaAdminCheckPermission("prod:category:all") + @OperationLog("商品分类-详情") + //@SaAdminCheckPermission("prod:category:info") public CzgResult get(@PathVariable("id") Long id) { - ShopProdCategoryDTO data = null; - + AssertUtil.isNull(id, "{}不能为空", "id"); + ShopProdCategoryDTO data = shopProdCategoryService.get(id); return CzgResult.success(data); } @PostMapping - @OperationLog("保存") - @SaAdminCheckPermission("prod:category:all") + @OperationLog("商品分类-新增") + //@SaAdminCheckPermission("prod:category:save") public CzgResult save(@RequestBody ShopProdCategoryDTO dto) { //效验数据 ValidatorUtil.validateEntity(dto, InsertGroup.class, DefaultGroup.class); - //shopProdCategoryService.save(dto); + shopProdCategoryService.save(dto); return CzgResult.success(); } @PutMapping - @OperationLog("修改") - @SaAdminCheckPermission("prod:category:all") + @OperationLog("商品分类-修改") + //@SaAdminCheckPermission("prod:category:update") public CzgResult update(@RequestBody ShopProdCategoryDTO dto) { //效验数据 ValidatorUtil.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); - //shopProdCategoryService.update(dto); + shopProdCategoryService.update(dto); return CzgResult.success(); } - @DeleteMapping - @OperationLog("删除") - @SaAdminCheckPermission("prod:category:all") - public CzgResult delete(@RequestBody Long[] ids) { + @DeleteMapping("{id}") + @OperationLog("商品分类-删除") + //@SaAdminCheckPermission("prod:unit:delete") + public CzgResult delete(@PathVariable("id") Long id) { //效验数据 - Assert.notNull(ids, "{}不能为空", "id"); - AssertUtil.isArrayEmpty(ids, "请求id数组不能为空"); - AssertUtil.isArrayEmpty(ids, "请求{}{}数组不能为空", "id", "的"); - Validator.validateBirthday("2022-12-12", "生日格式不正确"); - - //shopProdCategoryService.delete(ids); - + AssertUtil.isNull(id, "{}不能为空", "id"); + shopProdCategoryService.delete(id); return CzgResult.success(); } + + @PostMapping("disable/{id}") + @OperationLog("商品分类-禁用") + //@SaAdminCheckPermission("prod:unit:able") + public CzgResult disable(@PathVariable("id") Long id) { + //效验数据 + AssertUtil.isNull(id, "{}不能为空", "id"); + shopProdCategoryService.disable(id); + return CzgResult.success(); + } + + @PostMapping("enable/{id}") + @OperationLog("商品分类-启用") + //@SaAdminCheckPermission("prod:unit:able") + public CzgResult enable(@PathVariable("id") Long id) { + //效验数据 + AssertUtil.isNull(id, "{}不能为空", "id"); + shopProdCategoryService.enable(id); + return CzgResult.success(); + } + } \ No newline at end of file diff --git a/cash-api/product-server/src/main/java/com/czg/controller/ShopProdUnitController.java b/cash-api/product-server/src/main/java/com/czg/controller/ShopProdUnitController.java index 8360e72d..b08f2840 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/ShopProdUnitController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/ShopProdUnitController.java @@ -46,7 +46,7 @@ public class ShopProdUnitController { } @GetMapping("{id}") - @OperationLog("商品单位-信息") + @OperationLog("商品单位-详情") //@SaAdminCheckPermission("prod:unit:info") public CzgResult get(@PathVariable("id") Long id) { AssertUtil.isNull(id, "{}不能为空", "id"); @@ -55,7 +55,7 @@ public class ShopProdUnitController { } @PostMapping - @OperationLog("商品单位-保存") + @OperationLog("商品单位-新增") //@SaAdminCheckPermission("prod:unit:save") public CzgResult save(@RequestBody ShopProdUnitDTO dto) { //效验数据 @@ -79,7 +79,7 @@ public class ShopProdUnitController { } @DeleteMapping("{id}") - @OperationLog("商品单位-启用") + @OperationLog("商品单位-删除") //@SaAdminCheckPermission("prod:unit:delete") public CzgResult delete(@PathVariable("id") Long id) { //效验数据 diff --git a/cash-api/product-server/src/main/java/com/czg/controller/ShopProductSpecController.java b/cash-api/product-server/src/main/java/com/czg/controller/ShopProductSpecController.java new file mode 100644 index 00000000..29fb45d2 --- /dev/null +++ b/cash-api/product-server/src/main/java/com/czg/controller/ShopProductSpecController.java @@ -0,0 +1,100 @@ +package com.czg.controller; + +import com.czg.log.annotation.OperationLog; +import com.czg.product.dto.ShopProductSpecDTO; +import com.czg.product.service.ShopProductSpecService; +import com.czg.resp.CzgResult; +import com.czg.utils.AssertUtil; +import com.czg.validator.ValidatorUtil; +import com.czg.validator.group.DefaultGroup; +import com.czg.validator.group.InsertGroup; +import com.czg.validator.group.UpdateGroup; +import lombok.AllArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +/** +* 商品规格 +* +* @author Tankaikai tankaikai@aliyun.com +* @since 1.0 2025-02-13 +*/ +@AllArgsConstructor +@RestController +@RequestMapping("/admin/prod/spec") +public class ShopProductSpecController { + private final ShopProductSpecService shopProductSpecService; + + @GetMapping("list") + @OperationLog("商品规格-列表") + //@SaAdminCheckPermission("product:spec:list") + public CzgResult> list(ShopProductSpecDTO param){ + List data = shopProductSpecService.list(param); + return CzgResult.success(data); + } + + @GetMapping("{id}") + @OperationLog("商品规格-详情") + //@SaAdminCheckPermission("product:spec:info") + public CzgResult get(@PathVariable("id") Long id){ + AssertUtil.isNull(id, "{}不能为空", "id"); + ShopProductSpecDTO data = shopProductSpecService.get(id); + return CzgResult.success(data); + } + + @PostMapping + @OperationLog("商品规格-新增") + //@SaAdminCheckPermission("product:spec:save") + public CzgResult save(@RequestBody ShopProductSpecDTO dto){ + //效验数据 + ValidatorUtil.validateEntity(dto, InsertGroup.class, DefaultGroup.class); + + shopProductSpecService.save(dto); + + return CzgResult.success(); + } + + @PutMapping + @OperationLog("商品规格-修改") + //@SaAdminCheckPermission("product:spec:update") + public CzgResult update(@RequestBody ShopProductSpecDTO dto){ + //效验数据 + ValidatorUtil.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + shopProductSpecService.update(dto); + + return CzgResult.success(); + } + + @DeleteMapping("{id}") + @OperationLog("商品规格-删除") + //@SaAdminCheckPermission("product:spec:delete") + public CzgResult delete(@PathVariable("id") Long id){ + //效验数据 + AssertUtil.isNull(id, "{}不能为空", "id"); + shopProductSpecService.delete(id); + return CzgResult.success(); + } + + @PostMapping("disable/{id}") + @OperationLog("商品规格-禁用") + //@SaAdminCheckPermission("product:spec:able") + public CzgResult disable(@PathVariable("id") Long id) { + //效验数据 + AssertUtil.isNull(id, "{}不能为空", "id"); + shopProductSpecService.disable(id); + return CzgResult.success(); + } + + @PostMapping("enable/{id}") + @OperationLog("商品规格-启用") + //@SaAdminCheckPermission("product:spec:able") + public CzgResult enable(@PathVariable("id") Long id) { + //效验数据 + AssertUtil.isNull(id, "{}不能为空", "id"); + shopProductSpecService.enable(id); + return CzgResult.success(); + } +} \ No newline at end of file diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProdCategoryDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProdCategoryDTO.java index 9f02d72d..05a4729c 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProdCategoryDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProdCategoryDTO.java @@ -1,8 +1,15 @@ package com.czg.product.dto; import com.alibaba.fastjson2.annotation.JSONField; +import com.czg.validator.group.DefaultGroup; +import com.czg.validator.group.InsertGroup; +import com.czg.validator.group.UpdateGroup; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Null; import lombok.Data; +import java.io.Serial; import java.io.Serializable; import java.time.LocalDateTime; @@ -14,15 +21,20 @@ import java.time.LocalDateTime; */ @Data public class ShopProdCategoryDTO implements Serializable { + + @Serial private static final long serialVersionUID = 1L; /** - * 自增id + * id */ - private Integer id; + @Null(message = "ID必须为空", groups = InsertGroup.class) + @NotNull(message = "ID不能为空", groups = UpdateGroup.class) + private Long id; /** * 分类名称 */ + @NotBlank(message = "分类名称不能为空", groups = DefaultGroup.class) private String name; /** * 简称 @@ -31,7 +43,7 @@ public class ShopProdCategoryDTO implements Serializable { /** * 上级分类id-为0则表示是顶级 */ - private String pid; + private Long pid; /** * 图标 */ @@ -39,11 +51,7 @@ public class ShopProdCategoryDTO implements Serializable { /** * 店铺Id */ - private String shopId; - /** - * 是否显示:1显示 0不显示 - */ - private Integer isShow; + private Long shopId; /** * 分类描述 */ @@ -51,13 +59,24 @@ public class ShopProdCategoryDTO implements Serializable { /** * 排序 */ + @NotNull(message = "排序值不能为空", groups = DefaultGroup.class) private Integer sort; /** * 关键词 */ private String keyWord; + /** + * 状态 0-禁用 1-启用 + */ + private Integer status; + /** + * 创建时间 + */ @JSONField(format = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; + /** + * 更新时间 + */ @JSONField(format = "yyyy-MM-dd HH:mm:ss") private LocalDateTime updateTime; diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProdUnitDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProdUnitDTO.java index 6aa0ae61..e98d8fd1 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProdUnitDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProdUnitDTO.java @@ -25,7 +25,7 @@ public class ShopProdUnitDTO implements Serializable { /** * id */ - @Null(message = "ID必须为空}", groups = InsertGroup.class) + @Null(message = "ID必须为空", groups = InsertGroup.class) @NotNull(message = "ID不能为空", groups = UpdateGroup.class) private Long id; /** diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProductSpecDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProductSpecDTO.java new file mode 100644 index 00000000..0ad11a37 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProductSpecDTO.java @@ -0,0 +1,77 @@ +package com.czg.product.dto; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.czg.utils.TreeNode; +import com.czg.validator.group.DefaultGroup; +import com.czg.validator.group.InsertGroup; +import com.czg.validator.group.UpdateGroup; +import jakarta.validation.constraints.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** +* 商品规格 +* +* @author Tankaikai tankaikai@aliyun.com +* @since 1.0 2025-02-13 +*/ +@Data +@EqualsAndHashCode(callSuper = true) +public class ShopProductSpecDTO extends TreeNode implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + @Null(message = "ID必须为空", groups = InsertGroup.class) + @NotNull(message = "ID不能为空", groups = UpdateGroup.class) + private Long id; + /** + * 规格名称 + */ + @NotBlank(message = "规格名称不能为空", groups = DefaultGroup.class) + private String name; + /** + * 规格级别 + */ + @NotNull(message = "规格级别不能为空", groups = DefaultGroup.class) + @Min(value = 1, message = "排序值不能小于1", groups = DefaultGroup.class) + @Max(value = 3, message = "排序值不能大于3", groups = DefaultGroup.class) + private Integer level; + /** + * 排序 + */ + @NotNull(message = "排序值不能为空", groups = DefaultGroup.class) + @Min(value = 0, message = "排序值不能小于0", groups = DefaultGroup.class) + private Integer sort; + /** + * 上级id + */ + @NotNull(message = "请选择上级规格", groups = DefaultGroup.class) + private Long pid; + /** + * 店铺 id + */ + private Long shopId; + /** + * 状态 0-禁用 1-启用 + */ + private Integer status; + /** + * 创建时间 + */ + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + /** + * 更新时间 + */ + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdCategory.java b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdCategory.java index 0c078040..1706cd5b 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdCategory.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdCategory.java @@ -1,8 +1,10 @@ package com.czg.product.entity; +import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.KeyType; import com.mybatisflex.annotation.Table; +import com.mybatisflex.core.keygen.KeyGenerators; import lombok.Data; import java.io.Serial; @@ -23,9 +25,9 @@ public class ShopProdCategory implements Serializable { private static final long serialVersionUID = 1L; /** - * 自增id + * id */ - @Id(keyType = KeyType.Auto) + @Id(keyType = KeyType.Generator, value = KeyGenerators.snowFlakeId) private Long id; /** * 分类名称 @@ -38,7 +40,7 @@ public class ShopProdCategory implements Serializable { /** * 上级分类id-为0则表示是顶级 */ - private String pid; + private Long pid; /** * 图标 */ @@ -48,10 +50,6 @@ public class ShopProdCategory implements Serializable { */ private Long shopId; /** - * 是否显示:1显示 0不显示 - */ - private Integer isShow; - /** * 分类描述 */ private String detail; @@ -63,12 +61,18 @@ public class ShopProdCategory implements Serializable { * 关键词 */ private String keyWord; + /** + * 状态 0-禁用 1-启用 + */ + private Integer status; /** * 创建时间 */ + @Column(onInsertValue = "now()") private LocalDateTime createTime; /** - * 修改时间 + * 更新时间 */ + @Column(onUpdateValue = "now()") private LocalDateTime updateTime; } \ No newline at end of file diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProductSpec.java b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProductSpec.java new file mode 100644 index 00000000..96c5aed8 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProductSpec.java @@ -0,0 +1,63 @@ +package com.czg.product.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import com.mybatisflex.core.keygen.KeyGenerators; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 商品规格 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-02-13 + */ +@Data +@Table("tb_shop_product_spec") +public class ShopProductSpec implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + @Id(keyType = KeyType.Generator, value = KeyGenerators.snowFlakeId) + private Long id; + /** + * 规格名称 + */ + private String name; + /** + * 规格级别 + */ + private Integer level; + /** + * 排序 + */ + private Integer sort; + /** + * 上级 id + */ + private Long pid; + /** + * 店铺 id + */ + private Long shopId; + /** + * 状态 0-禁用 1-启用 + */ + private Integer status; + /** + * 创建时间 + */ + private LocalDateTime createTime; + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} \ No newline at end of file diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopProdCategoryService.java b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopProdCategoryService.java index da55d98a..d807155d 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopProdCategoryService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopProdCategoryService.java @@ -1,8 +1,12 @@ package com.czg.product.service; +import com.czg.product.dto.ShopProdCategoryDTO; import com.czg.product.entity.ShopProdCategory; +import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.service.IService; +import java.util.List; + /** * 店铺商品分类 * @@ -11,4 +15,20 @@ import com.mybatisflex.core.service.IService; */ public interface ShopProdCategoryService extends IService { + Page page(ShopProdCategoryDTO param); + + List list(ShopProdCategoryDTO param); + + ShopProdCategoryDTO get(Long id); + + boolean save(ShopProdCategoryDTO dto); + + boolean update(ShopProdCategoryDTO dto); + + boolean delete(Long id); + + boolean disable(Long id); + + boolean enable(Long id); + } \ No newline at end of file diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopProductSpecService.java b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopProductSpecService.java new file mode 100644 index 00000000..e7d8c076 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopProductSpecService.java @@ -0,0 +1,33 @@ +package com.czg.product.service; + +import com.czg.product.dto.ShopProductSpecDTO; +import com.czg.product.entity.ShopProductSpec; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.service.IService; + +import java.util.List; + +/** + * 商品规格 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-02-13 + */ +public interface ShopProductSpecService extends IService { + Page page(ShopProductSpecDTO param); + + List list(ShopProductSpecDTO param); + + ShopProductSpecDTO get(Long id); + + boolean save(ShopProductSpecDTO dto); + + boolean delete(Long id); + + boolean update(ShopProductSpecDTO dto); + + boolean disable(Long id); + + boolean enable(Long id); + +} \ No newline at end of file diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/constant/GlobalConstant.java b/cash-common/cash-common-tools/src/main/java/com/czg/constant/GlobalConstant.java new file mode 100644 index 00000000..c1913376 --- /dev/null +++ b/cash-common/cash-common-tools/src/main/java/com/czg/constant/GlobalConstant.java @@ -0,0 +1,18 @@ + + +package com.czg.constant; + +/** + * 常量 + * + * @author admin admin@cashier.com + * @since 1.0.0 + */ +public interface GlobalConstant { + + /** + * 树形数据根节点标识 + */ + Long TREE_ROOT = 0L; + +} \ No newline at end of file diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/utils/TreeNode.java b/cash-common/cash-common-tools/src/main/java/com/czg/utils/TreeNode.java new file mode 100644 index 00000000..a3e48ca8 --- /dev/null +++ b/cash-common/cash-common-tools/src/main/java/com/czg/utils/TreeNode.java @@ -0,0 +1,35 @@ + + +package com.czg.utils; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 树节点,所有需要实现树节点的,都需要继承该类 + * + * @author admin admin@cashier.com + * @since 1.0.0 + */ +@Data +public class TreeNode implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + /** + * 主键 + */ + private Long id; + /** + * 上级ID + */ + private Long pid; + /** + * 子节点列表 + */ + private List children = new ArrayList<>(); + +} \ No newline at end of file diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/utils/TreeUtils.java b/cash-common/cash-common-tools/src/main/java/com/czg/utils/TreeUtils.java new file mode 100644 index 00000000..d10be71e --- /dev/null +++ b/cash-common/cash-common-tools/src/main/java/com/czg/utils/TreeUtils.java @@ -0,0 +1,72 @@ + + +package com.czg.utils; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * 树形结构工具类,如:菜单、部门等 + * + * @author admin admin@cashier.com + * @since 1.0.0 + */ +public class TreeUtils { + + /** + * 根据pid,构建树节点 + */ + public static List build(List treeNodes, Long pid) { + //pid不能为空 + AssertUtil.isNull(pid, "pid不能为空"); + + List treeList = new ArrayList<>(); + for(T treeNode : treeNodes) { + if (pid.equals(treeNode.getPid())) { + treeList.add(findChildren(treeNodes, treeNode)); + } + } + + return treeList; + } + + /** + * 查找子节点 + */ + private static T findChildren(List treeNodes, T rootNode) { + for(T treeNode : treeNodes) { + if(rootNode.getId().equals(treeNode.getPid())) { + rootNode.getChildren().add(findChildren(treeNodes, treeNode)); + } + } + return rootNode; + } + + /** + * 构建树节点 + */ + public static List build(List treeNodes) { + List result = new ArrayList<>(); + + //list转map + Map nodeMap = new LinkedHashMap<>(treeNodes.size()); + for(T treeNode : treeNodes){ + nodeMap.put(treeNode.getId(), treeNode); + } + + for(T node : nodeMap.values()) { + T parent = nodeMap.get(node.getPid()); + if(parent != null && !(node.getId().equals(parent.getId()))){ + parent.getChildren().add(node); + continue; + } + + result.add(node); + } + + return result; + } + +} \ No newline at end of file diff --git a/cash-service/product-service/src/main/java/com/czg/service/product/mapper/ShopProductSpecMapper.java b/cash-service/product-service/src/main/java/com/czg/service/product/mapper/ShopProductSpecMapper.java new file mode 100644 index 00000000..365c1773 --- /dev/null +++ b/cash-service/product-service/src/main/java/com/czg/service/product/mapper/ShopProductSpecMapper.java @@ -0,0 +1,16 @@ +package com.czg.service.product.mapper; + +import com.czg.product.entity.ShopProductSpec; +import com.mybatisflex.core.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** +* 商品规格 +* +* @author Tankaikai tankaikai@aliyun.com +* @since 1.0 2025-02-13 +*/ +@Mapper +public interface ShopProductSpecMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ShopProdCategoryServiceImpl.java b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ShopProdCategoryServiceImpl.java index eb123bf9..42c4f562 100644 --- a/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ShopProdCategoryServiceImpl.java +++ b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ShopProdCategoryServiceImpl.java @@ -1,11 +1,23 @@ package com.czg.service.product.service.impl; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.StrUtil; +import com.czg.enums.StatusEnum; +import com.czg.exception.CzgException; +import com.czg.product.dto.ShopProdCategoryDTO; import com.czg.product.entity.ShopProdCategory; import com.czg.product.service.ShopProdCategoryService; +import com.czg.sa.StpKit; import com.czg.service.product.mapper.ShopProdCategoryMapper; +import com.czg.utils.PageUtil; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.update.UpdateChain; import com.mybatisflex.spring.service.impl.ServiceImpl; import org.springframework.stereotype.Service; +import java.util.List; + /** * 店铺商品分类 * @@ -15,4 +27,89 @@ import org.springframework.stereotype.Service; @Service public class ShopProdCategoryServiceImpl extends ServiceImpl implements ShopProdCategoryService { + private QueryWrapper buildQueryWrapper(ShopProdCategoryDTO param) { + QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper(); + if (StrUtil.isNotEmpty(param.getName())) { + queryWrapper.like(ShopProdCategory::getName, param.getName()); + } + Long shopId = StpKit.USER.getLoginIdAsLong(); + queryWrapper.eq(ShopProdCategory::getShopId, shopId); + queryWrapper.orderBy(ShopProdCategory::getId, false); + return queryWrapper; + } + + @Override + public Page page(ShopProdCategoryDTO param) { + QueryWrapper queryWrapper = buildQueryWrapper(param); + return super.pageAs(PageUtil.buildPage(), queryWrapper, ShopProdCategoryDTO.class); + } + + @Override + public List list(ShopProdCategoryDTO param) { + QueryWrapper queryWrapper = buildQueryWrapper(param); + queryWrapper.eq(ShopProdCategory::getStatus, StatusEnum.ENABLED.value()); + return super.listAs(queryWrapper, ShopProdCategoryDTO.class); + } + + @Override + public ShopProdCategoryDTO get(Long id) { + Long shopId = StpKit.USER.getLoginIdAsLong(); + return super.getOneAs(query().eq(ShopProdCategory::getId, id).eq(ShopProdCategory::getShopId, shopId), ShopProdCategoryDTO.class); + } + + @Override + public boolean save(ShopProdCategoryDTO dto) { + Long shopId = StpKit.USER.getLoginIdAsLong(); + boolean exists = super.exists(query().eq(ShopProdCategory::getName, dto.getName()).eq(ShopProdCategory::getShopId, shopId)); + if (exists) { + throw new CzgException("商品分类已存在"); + } + ShopProdCategory entity = BeanUtil.copyProperties(dto, ShopProdCategory.class); + // 简称 + entity.setShortName(dto.getName()); + if(entity.getStatus() == null){ + entity.setStatus(StatusEnum.ENABLED.value()); + } + entity.setPid(0L); + entity.setShopId(shopId); + return super.save(entity); + } + + @Override + public boolean update(ShopProdCategoryDTO dto) { + Long shopId = StpKit.USER.getLoginIdAsLong(); + boolean exists = super.exists(query().eq(ShopProdCategory::getName, dto.getName()).eq(ShopProdCategory::getShopId, shopId).ne(ShopProdCategory::getId, dto.getId())); + if (exists) { + throw new CzgException("商品分类已存在"); + } + ShopProdCategory entity = BeanUtil.copyProperties(dto, ShopProdCategory.class); + return super.updateById(entity); + } + + @Override + public boolean delete(Long id) { + Long shopId = StpKit.USER.getLoginIdAsLong(); + return super.remove(query().eq(ShopProdCategory::getId, id).eq(ShopProdCategory::getShopId, shopId)); + } + + @Override + public boolean disable(Long id) { + Long shopId = StpKit.USER.getLoginIdAsLong(); + return UpdateChain.of(ShopProdCategory.class) + .set(ShopProdCategory::getStatus, StatusEnum.DISABLE.value()) + .eq(ShopProdCategory::getId, id) + .eq(ShopProdCategory::getShopId, shopId) + .update(); + } + + @Override + public boolean enable(Long id) { + Long shopId = StpKit.USER.getLoginIdAsLong(); + return UpdateChain.of(ShopProdCategory.class) + .set(ShopProdCategory::getStatus, StatusEnum.ENABLED.value()) + .eq(ShopProdCategory::getId, id) + .eq(ShopProdCategory::getShopId, shopId) + .update(); + } + } \ No newline at end of file diff --git a/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ShopProductSpecServiceImpl.java b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ShopProductSpecServiceImpl.java new file mode 100644 index 00000000..09df178b --- /dev/null +++ b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ShopProductSpecServiceImpl.java @@ -0,0 +1,145 @@ +package com.czg.service.product.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.StrUtil; +import com.czg.constant.GlobalConstant; +import com.czg.enums.StatusEnum; +import com.czg.exception.CzgException; +import com.czg.product.dto.ShopProductSpecDTO; +import com.czg.product.entity.ShopProdCategory; +import com.czg.product.entity.ShopProductSpec; +import com.czg.product.service.ShopProductSpecService; +import com.czg.sa.StpKit; +import com.czg.service.product.mapper.ShopProductSpecMapper; +import com.czg.utils.PageUtil; +import com.czg.utils.TreeUtils; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.update.UpdateChain; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.List; + + +/** + * 商品规格 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-02-13 + */ +@Service +public class ShopProductSpecServiceImpl extends ServiceImpl implements ShopProductSpecService { + + + private QueryWrapper buildQueryWrapper(ShopProductSpecDTO param) { + QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper(); + if (StrUtil.isNotEmpty(param.getName())) { + queryWrapper.like(ShopProductSpec::getName, param.getName()); + } + Long shopId = StpKit.USER.getLoginIdAsLong(); + queryWrapper.eq(ShopProductSpec::getShopId, shopId); + queryWrapper.orderBy(ShopProductSpec::getId, false); + return queryWrapper; + } + + @Override + public Page page(ShopProductSpecDTO param) { + QueryWrapper queryWrapper = buildQueryWrapper(param); + return super.pageAs(PageUtil.buildPage(), queryWrapper, ShopProductSpecDTO.class); + } + + @Override + public List list(ShopProductSpecDTO param) { + QueryWrapper queryWrapper = buildQueryWrapper(param); + queryWrapper.eq(ShopProductSpec::getStatus, StatusEnum.ENABLED.value()); + List list = super.listAs(queryWrapper, ShopProductSpecDTO.class); + return TreeUtils.build(list, GlobalConstant.TREE_ROOT); + } + + @Override + public ShopProductSpecDTO get(Long id) { + Long shopId = StpKit.USER.getLoginIdAsLong(); + return super.getOneAs(query().eq(ShopProductSpec::getId, id).eq(ShopProductSpec::getShopId, shopId), ShopProductSpecDTO.class); + } + + @Override + public boolean save(ShopProductSpecDTO dto) { + Long shopId = StpKit.USER.getLoginIdAsLong(); + boolean exists = super.exists(query() + .eq(ShopProductSpec::getName, dto.getName()) + .eq(ShopProductSpec::getLevel, dto.getLevel()) + .eq(ShopProductSpec::getShopId, shopId)); + if (exists) { + throw new CzgException("商品规格已存在"); + } + ShopProductSpec entity = BeanUtil.copyProperties(dto, ShopProductSpec.class); + entity.setStatus(StatusEnum.ENABLED.value()); + entity.setShopId(shopId); + return super.save(entity); + } + + @Override + public boolean update(ShopProductSpecDTO dto) { + //上级规格不能为自身 + if (dto.getId().equals(dto.getPid())) { + throw new CzgException("上级规格不能为自身"); + } + Long shopId = StpKit.USER.getLoginIdAsLong(); + boolean exists = super.exists(query() + .eq(ShopProductSpec::getName, dto.getName()) + .eq(ShopProductSpec::getLevel, dto.getLevel()) + .eq(ShopProductSpec::getShopId, shopId) + .ne(ShopProductSpec::getId, dto.getId())); + if (exists) { + throw new CzgException("商品规格已存在"); + } + ShopProductSpec entity = BeanUtil.copyProperties(dto, ShopProductSpec.class); + return super.updateById(entity); + } + + @Override + public boolean delete(Long id) { + Long shopId = StpKit.USER.getLoginIdAsLong(); + return super.remove( + query().eq(ShopProdCategory::getShopId, shopId) + .and(wrapper -> { + wrapper.eq(ShopProductSpec::getId, id) + .or(wrapper1 -> { + wrapper1.eq(ShopProductSpec::getPid, id); + }); + }) + ); + } + + @Override + public boolean disable(Long id) { + Long shopId = StpKit.USER.getLoginIdAsLong(); + return UpdateChain.of(ShopProductSpec.class) + .set(ShopProductSpec::getStatus, StatusEnum.DISABLE.value()) + .where(ShopProductSpec::getShopId).eq(shopId) + .and(wrapper -> { + wrapper.eq(ShopProductSpec::getId, id) + .or(wrapper1 -> { + wrapper1.eq(ShopProductSpec::getPid, id); + }); + }) + .update(); + } + + @Override + public boolean enable(Long id) { + Long shopId = StpKit.USER.getLoginIdAsLong(); + return UpdateChain.of(ShopProductSpec.class) + .set(ShopProductSpec::getStatus, StatusEnum.ENABLED.value()) + .where(ShopProductSpec::getShopId).eq(shopId) + .and(wrapper -> { + wrapper.eq(ShopProductSpec::getId, id) + .or(wrapper1 -> { + wrapper1.eq(ShopProductSpec::getPid, id); + }); + }) + .update(); + } + +} \ No newline at end of file