商品模块代码提交
This commit is contained in:
@@ -1,99 +1,102 @@
|
|||||||
package com.czg.controller;
|
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.log.annotation.OperationLog;
|
||||||
import com.czg.product.dto.ProductDTO;
|
import com.czg.product.dto.ProductDTO;
|
||||||
import com.czg.product.service.ProductService;
|
import com.czg.product.service.ProductService;
|
||||||
import com.czg.resp.CzgResult;
|
import com.czg.resp.CzgResult;
|
||||||
import com.czg.utils.AssertUtil;
|
import com.czg.utils.AssertUtil;
|
||||||
import com.czg.validator.ValidatorUtil;
|
|
||||||
import com.czg.validator.group.DefaultGroup;
|
import com.czg.validator.group.DefaultGroup;
|
||||||
import com.czg.validator.group.InsertGroup;
|
import com.czg.validator.group.InsertGroup;
|
||||||
import com.czg.validator.group.UpdateGroup;
|
import com.czg.validator.group.UpdateGroup;
|
||||||
import com.mybatisflex.core.paginate.Page;
|
import com.mybatisflex.core.paginate.Page;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品
|
* 商品
|
||||||
*
|
*
|
||||||
* @author Tankaikai tankaikai@aliyun.com
|
* @author Tankaikai tankaikai@aliyun.com
|
||||||
* @since 1.0 2025-02-10
|
* @since 1.0 2025-02-16
|
||||||
*/
|
*/
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/admin/prod/product")
|
@RequestMapping("/admin/product")
|
||||||
public class ProductController {
|
public class ProductController {
|
||||||
private final ProductService productService;
|
private final ProductService productService;
|
||||||
|
|
||||||
@GetMapping("page")
|
@GetMapping("page")
|
||||||
@OperationLog("分页")
|
@OperationLog("商品-分页")
|
||||||
@SaAdminCheckPermission("prod:product:all")
|
//@SaAdminCheckPermission("product:page")
|
||||||
public CzgResult<Page<ProductDTO>> page(@RequestParam Map<String, Object> params) {
|
public CzgResult<Page<ProductDTO>> getProductPage(ProductDTO param) {
|
||||||
Page<ProductDTO> data = productService.pageAs(null, null, ProductDTO.class);
|
Page<ProductDTO> data = productService.getProductPage(param);
|
||||||
return CzgResult.success(data);
|
return CzgResult.success(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("list")
|
@GetMapping("list")
|
||||||
@OperationLog("列表")
|
@OperationLog("商品-列表")
|
||||||
@SaAdminCheckPermission("prod:product:all")
|
//@SaAdminCheckPermission("product:list")
|
||||||
public CzgResult<List<ProductDTO>> list(@RequestParam Map<String, Object> params) {
|
public CzgResult<List<ProductDTO>> getProductList(ProductDTO param) {
|
||||||
List<ProductDTO> data = null;
|
List<ProductDTO> data = productService.getProductList(param);
|
||||||
|
|
||||||
return CzgResult.success(data);
|
return CzgResult.success(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("{id}")
|
@GetMapping("{id}")
|
||||||
@OperationLog("信息")
|
@OperationLog("商品-详情")
|
||||||
@SaAdminCheckPermission("prod:product:all")
|
//@SaAdminCheckPermission("product:info")
|
||||||
public CzgResult<ProductDTO> get(@PathVariable("id") Long id) {
|
public CzgResult<ProductDTO> getProductById(@PathVariable("id") Long id) {
|
||||||
ProductDTO data = null;
|
AssertUtil.isNull(id, "{}不能为空", "id");
|
||||||
|
ProductDTO data = productService.getProductById(id);
|
||||||
return CzgResult.success(data);
|
return CzgResult.success(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@OperationLog("保存")
|
@OperationLog("商品-新增")
|
||||||
@SaAdminCheckPermission("prod:product:all")
|
//@SaAdminCheckPermission("product:add")
|
||||||
public CzgResult<Void> save(@RequestBody ProductDTO dto) {
|
public CzgResult<Void> addProduct(@RequestBody @Validated({InsertGroup.class, DefaultGroup.class}) ProductDTO dto) {
|
||||||
//效验数据
|
AssertUtil.isListEmpty(dto.getSkuList(), "商品SKU不能为空");
|
||||||
ValidatorUtil.validateEntity(dto, InsertGroup.class, DefaultGroup.class);
|
productService.addProduct(dto);
|
||||||
|
|
||||||
//productService.save(dto);
|
|
||||||
|
|
||||||
return CzgResult.success();
|
return CzgResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping
|
@PutMapping
|
||||||
@OperationLog("修改")
|
@OperationLog("商品-修改")
|
||||||
@SaAdminCheckPermission("prod:product:all")
|
//@SaAdminCheckPermission("product:update")
|
||||||
public CzgResult<Void> update(@RequestBody ProductDTO dto) {
|
public CzgResult<Void> updateProduct(@RequestBody @Validated({UpdateGroup.class, DefaultGroup.class}) ProductDTO dto) {
|
||||||
//效验数据
|
productService.updateProduct(dto);
|
||||||
ValidatorUtil.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
|
|
||||||
|
|
||||||
//productService.update(dto);
|
|
||||||
|
|
||||||
return CzgResult.success();
|
return CzgResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping
|
@DeleteMapping("{id}")
|
||||||
@OperationLog("删除")
|
@OperationLog("商品-删除")
|
||||||
@SaAdminCheckPermission("prod:product:all")
|
//@SaAdminCheckPermission("product:delete")
|
||||||
public CzgResult<Void> delete(@RequestBody Long[] ids) {
|
public CzgResult<Void> deleteProduct(@PathVariable("id") Long id) {
|
||||||
//效验数据
|
//效验数据
|
||||||
Assert.notNull(ids, "{}不能为空", "id");
|
AssertUtil.isNull(id, "{}不能为空", "id");
|
||||||
AssertUtil.isArrayEmpty(ids, "请求id数组不能为空");
|
productService.deleteProduct(id);
|
||||||
AssertUtil.isArrayEmpty(ids, "请求{}{}数组不能为空", "id", "的");
|
return CzgResult.success();
|
||||||
Validator.validateBirthday("2022-12-12", "生日格式不正确");
|
}
|
||||||
|
|
||||||
//productService.delete(ids);
|
@PostMapping("disable/{id}")
|
||||||
|
@OperationLog("商品-禁用")
|
||||||
|
//@SaAdminCheckPermission("product:able")
|
||||||
|
public CzgResult<Void> disableProduct(@PathVariable("id") Long id) {
|
||||||
|
//效验数据
|
||||||
|
AssertUtil.isNull(id, "{}不能为空", "id");
|
||||||
|
productService.disableProduct(id);
|
||||||
|
return CzgResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("enable/{id}")
|
||||||
|
@OperationLog("商品-启用")
|
||||||
|
//@SaAdminCheckPermission("product:able")
|
||||||
|
public CzgResult<Void> enableProduct(@PathVariable("id") Long id) {
|
||||||
|
//效验数据
|
||||||
|
AssertUtil.isNull(id, "{}不能为空", "id");
|
||||||
|
productService.enableProduct(id);
|
||||||
return CzgResult.success();
|
return CzgResult.success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package com.czg.product.dto;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品SKU
|
||||||
|
*
|
||||||
|
* @author Tankaikai tankaikai@aliyun.com
|
||||||
|
* @since 1.0 2025-02-16
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ProdSkuDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* id
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 店铺id
|
||||||
|
*/
|
||||||
|
private Long shopId;
|
||||||
|
/**
|
||||||
|
* 条形码
|
||||||
|
*/
|
||||||
|
private String barCode;
|
||||||
|
/**
|
||||||
|
* 商品Id
|
||||||
|
*/
|
||||||
|
private Long productId;
|
||||||
|
/**
|
||||||
|
* 原价
|
||||||
|
*/
|
||||||
|
private BigDecimal originPrice;
|
||||||
|
/**
|
||||||
|
* 成本价
|
||||||
|
*/
|
||||||
|
private BigDecimal costPrice;
|
||||||
|
/**
|
||||||
|
* 会员价
|
||||||
|
*/
|
||||||
|
private BigDecimal memberPrice;
|
||||||
|
/**
|
||||||
|
* 售价
|
||||||
|
*/
|
||||||
|
private BigDecimal salePrice;
|
||||||
|
/**
|
||||||
|
* 起售数量
|
||||||
|
*/
|
||||||
|
private Integer suitNum;
|
||||||
|
/**
|
||||||
|
* 规格详情
|
||||||
|
*/
|
||||||
|
private String specInfo;
|
||||||
|
/**
|
||||||
|
* sku图片
|
||||||
|
*/
|
||||||
|
private String coverImg;
|
||||||
|
/**
|
||||||
|
* 重量
|
||||||
|
*/
|
||||||
|
private BigDecimal weight;
|
||||||
|
/**
|
||||||
|
* 销量
|
||||||
|
*/
|
||||||
|
private BigDecimal realSalesNumber;
|
||||||
|
/**
|
||||||
|
* 是否售罄
|
||||||
|
*/
|
||||||
|
private Integer isPauseSale;
|
||||||
|
/**
|
||||||
|
* 是否上架
|
||||||
|
*/
|
||||||
|
private Integer isGrounding;
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
/**
|
||||||
|
* 逻辑删除字段 0否 1 删除
|
||||||
|
*/
|
||||||
|
private Integer isDel;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,50 +1,87 @@
|
|||||||
package com.czg.product.dto;
|
package com.czg.product.dto;
|
||||||
|
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
|
import com.czg.product.vo.ProductGroupVo;
|
||||||
|
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.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品
|
* 商品
|
||||||
*
|
*
|
||||||
* @author Tankaikai tankaikai@aliyun.com
|
* @author Tankaikai tankaikai@aliyun.com
|
||||||
* @since 1.0 2025-02-10
|
* @since 1.0 2025-02-16
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class ProductDTO implements Serializable {
|
public class ProductDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
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;
|
||||||
/**
|
/**
|
||||||
* 商品分类
|
* 商品分类
|
||||||
*/
|
*/
|
||||||
private String categoryId;
|
@NotNull(message = "商品分类不能为空", groups = DefaultGroup.class)
|
||||||
|
private Long categoryId;
|
||||||
|
/**
|
||||||
|
* 商品分类名称
|
||||||
|
*/
|
||||||
|
private String categoryName;
|
||||||
/**
|
/**
|
||||||
* 商品规格
|
* 商品规格
|
||||||
*/
|
*/
|
||||||
private Integer specId;
|
private Long specId;
|
||||||
|
/**
|
||||||
|
* 商品规格名称
|
||||||
|
*/
|
||||||
|
private String specName;
|
||||||
|
/**
|
||||||
|
* 商品规格完整名称
|
||||||
|
*/
|
||||||
|
private String specFullName;
|
||||||
/**
|
/**
|
||||||
* 单位Id
|
* 单位Id
|
||||||
*/
|
*/
|
||||||
private Integer unitId;
|
@NotNull(message = "商品单位不能为空", groups = DefaultGroup.class)
|
||||||
private String shopId;
|
private Long unitId;
|
||||||
|
/**
|
||||||
|
* 商品单位名称
|
||||||
|
*/
|
||||||
|
private String unitName;
|
||||||
|
/**
|
||||||
|
* 店铺id
|
||||||
|
*/
|
||||||
|
private Long shopId;
|
||||||
/**
|
/**
|
||||||
* 商品名称
|
* 商品名称
|
||||||
*/
|
*/
|
||||||
|
@NotBlank(message = "商品名称不能为空", groups = DefaultGroup.class)
|
||||||
private String name;
|
private String name;
|
||||||
/**
|
/**
|
||||||
* 短标题--促销语
|
* 短标题--促销语
|
||||||
*/
|
*/
|
||||||
private String shortTitle;
|
private String shortTitle;
|
||||||
/**
|
/**
|
||||||
* 单规格商品 single 多规格商品 sku 套餐商品 package 称重商品 weigh 团购券 coupon
|
* 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券
|
||||||
*/
|
*/
|
||||||
|
@NotBlank(message = "商品类型不能为空", groups = DefaultGroup.class)
|
||||||
private String type;
|
private String type;
|
||||||
/**
|
/**
|
||||||
* 0 固定套餐 1可选套餐
|
* 0 固定套餐 1可选套餐
|
||||||
@@ -53,15 +90,17 @@ public class ProductDTO implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 包装费
|
* 包装费
|
||||||
*/
|
*/
|
||||||
|
@NotNull(message = "打包费不能为空", groups = DefaultGroup.class)
|
||||||
private BigDecimal packFee;
|
private BigDecimal packFee;
|
||||||
/**
|
/**
|
||||||
* 商品封面图
|
* 商品封面图
|
||||||
*/
|
*/
|
||||||
|
@NotBlank(message = "商品名称不能为空", groups = DefaultGroup.class)
|
||||||
private String coverImg;
|
private String coverImg;
|
||||||
/**
|
/**
|
||||||
* 商品图片(第一张为缩略图,其他为详情)
|
* 商品图片(第一张为缩略图,其他为详情)
|
||||||
*/
|
*/
|
||||||
private String images;
|
private Object images;
|
||||||
/**
|
/**
|
||||||
* 套餐内容
|
* 套餐内容
|
||||||
*/
|
*/
|
||||||
@@ -73,23 +112,30 @@ public class ProductDTO implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 称重 价格/千克
|
* 称重 价格/千克
|
||||||
*/
|
*/
|
||||||
|
@NotNull(message = "重量不能为空", groups = DefaultGroup.class)
|
||||||
private BigDecimal weight;
|
private BigDecimal weight;
|
||||||
/**
|
/**
|
||||||
* 是否允许临时改价
|
* 是否允许临时改价
|
||||||
*/
|
*/
|
||||||
private Integer isTempPrice;
|
@NotNull(message = "是否允许临时改价不能为空", groups = DefaultGroup.class)
|
||||||
|
private Integer isAllowTempModifyPrice;
|
||||||
/**
|
/**
|
||||||
* 周 数组 'Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday'
|
* 周 数组 'Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday'
|
||||||
*/
|
*/
|
||||||
|
@NotBlank(message = "定时上下架周期不能为空", groups = DefaultGroup.class)
|
||||||
private String days;
|
private String days;
|
||||||
/**
|
/**
|
||||||
* 可用开始时间
|
* 可用开始时间
|
||||||
*/
|
*/
|
||||||
private Object startTime;
|
@NotNull(message = "可用开始时间", groups = DefaultGroup.class)
|
||||||
|
@JSONField(format = "HH:mm:ss")
|
||||||
|
private LocalTime startTime;
|
||||||
/**
|
/**
|
||||||
* 可用结束时间
|
* 可用结束时间
|
||||||
*/
|
*/
|
||||||
private Object endTime;
|
@NotNull(message = "可用结束时间", groups = DefaultGroup.class)
|
||||||
|
@JSONField(format = "HH:mm:ss")
|
||||||
|
private LocalTime endTime;
|
||||||
/**
|
/**
|
||||||
* 规格详情
|
* 规格详情
|
||||||
*/
|
*/
|
||||||
@@ -97,14 +143,19 @@ public class ProductDTO implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 排序
|
* 排序
|
||||||
*/
|
*/
|
||||||
|
@NotNull(message = "排序值不能为空", groups = DefaultGroup.class)
|
||||||
|
@Min(value = 1, message = "排序值不能小于1", groups = DefaultGroup.class)
|
||||||
|
@Max(value = Integer.MAX_VALUE, message = "排序值不能大于" + Integer.MAX_VALUE, groups = DefaultGroup.class)
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
/**
|
/**
|
||||||
* 是否热销
|
* 是否热销
|
||||||
*/
|
*/
|
||||||
|
@NotNull(message = "是否推荐不能为空", groups = DefaultGroup.class)
|
||||||
private Integer isHot;
|
private Integer isHot;
|
||||||
/**
|
/**
|
||||||
* 是否开启库存
|
* 是否开启库存
|
||||||
*/
|
*/
|
||||||
|
@NotNull(message = "库存开关不能为空", groups = DefaultGroup.class)
|
||||||
private Integer isStock;
|
private Integer isStock;
|
||||||
/**
|
/**
|
||||||
* 是否售罄
|
* 是否售罄
|
||||||
@@ -121,13 +172,20 @@ public class ProductDTO implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 是否上架
|
* 是否上架
|
||||||
*/
|
*/
|
||||||
|
@NotNull(message = "是否上架不能为空", groups = DefaultGroup.class)
|
||||||
private Integer isSale;
|
private Integer isSale;
|
||||||
/**
|
/**
|
||||||
* 退款是否退回库存
|
* 退款是否退回库存
|
||||||
*/
|
*/
|
||||||
private Integer isRefundStock;
|
private Integer isRefundStock;
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
private LocalDateTime updateTime;
|
private LocalDateTime updateTime;
|
||||||
/**
|
/**
|
||||||
@@ -135,4 +193,14 @@ public class ProductDTO implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private Integer isDel;
|
private Integer isDel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品规格列表
|
||||||
|
*/
|
||||||
|
private List<ProdSkuDTO> skuList;
|
||||||
|
|
||||||
|
private List<ProductGroupVo> proGroupVo;
|
||||||
|
|
||||||
|
public Object getImages() {
|
||||||
|
return JSON.parseArray(Convert.toStr(images, "[]"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -45,8 +45,8 @@ public class ShopProdSpecDTO extends TreeNode<ShopProdSpecDTO> implements Serial
|
|||||||
* 规格级别
|
* 规格级别
|
||||||
*/
|
*/
|
||||||
@NotNull(message = "规格级别不能为空", groups = DefaultGroup.class)
|
@NotNull(message = "规格级别不能为空", groups = DefaultGroup.class)
|
||||||
@Min(value = 1, message = "排序值不能小于1", groups = DefaultGroup.class)
|
@Min(value = 1, message = "规格级别不能小于1", groups = DefaultGroup.class)
|
||||||
@Max(value = 3, message = "排序值不能大于3", groups = DefaultGroup.class)
|
@Max(value = 3, message = "规格级别不能大于3", groups = DefaultGroup.class)
|
||||||
private Integer level;
|
private Integer level;
|
||||||
/**
|
/**
|
||||||
* 排序
|
* 排序
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
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;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品SKU
|
||||||
|
*
|
||||||
|
* @author Tankaikai tankaikai@aliyun.com
|
||||||
|
* @since 1.0 2025-02-16
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Table("tb_prod_sku")
|
||||||
|
public class ProdSku implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* id
|
||||||
|
*/
|
||||||
|
@Id(keyType = KeyType.Generator, value = KeyGenerators.snowFlakeId)
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 店铺id
|
||||||
|
*/
|
||||||
|
private Long shopId;
|
||||||
|
/**
|
||||||
|
* 条形码
|
||||||
|
*/
|
||||||
|
private String barCode;
|
||||||
|
/**
|
||||||
|
* 商品Id
|
||||||
|
*/
|
||||||
|
private Long productId;
|
||||||
|
/**
|
||||||
|
* 原价
|
||||||
|
*/
|
||||||
|
private BigDecimal originPrice;
|
||||||
|
/**
|
||||||
|
* 成本价
|
||||||
|
*/
|
||||||
|
private BigDecimal costPrice;
|
||||||
|
/**
|
||||||
|
* 会员价
|
||||||
|
*/
|
||||||
|
private BigDecimal memberPrice;
|
||||||
|
/**
|
||||||
|
* 售价
|
||||||
|
*/
|
||||||
|
private BigDecimal salePrice;
|
||||||
|
/**
|
||||||
|
* 起售数量
|
||||||
|
*/
|
||||||
|
private Integer suitNum;
|
||||||
|
/**
|
||||||
|
* 规格详情
|
||||||
|
*/
|
||||||
|
private String specInfo;
|
||||||
|
private String coverImg;
|
||||||
|
private BigDecimal weight;
|
||||||
|
/**
|
||||||
|
* 销量
|
||||||
|
*/
|
||||||
|
private BigDecimal realSalesNumber;
|
||||||
|
/**
|
||||||
|
* 是否售罄
|
||||||
|
*/
|
||||||
|
private Integer isPauseSale;
|
||||||
|
/**
|
||||||
|
* 是否上架
|
||||||
|
*/
|
||||||
|
private Integer isGrounding;
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@Column(onInsertValue = "now()")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@Column(onInsertValue = "now()", onUpdateValue = "now()")
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
/**
|
||||||
|
* 逻辑删除字段 0否 1 删除
|
||||||
|
*/
|
||||||
|
private Integer isDel;
|
||||||
|
}
|
||||||
@@ -1,20 +1,23 @@
|
|||||||
package com.czg.product.entity;
|
package com.czg.product.entity;
|
||||||
|
|
||||||
|
import com.mybatisflex.annotation.Column;
|
||||||
import com.mybatisflex.annotation.Id;
|
import com.mybatisflex.annotation.Id;
|
||||||
import com.mybatisflex.annotation.KeyType;
|
import com.mybatisflex.annotation.KeyType;
|
||||||
import com.mybatisflex.annotation.Table;
|
import com.mybatisflex.annotation.Table;
|
||||||
|
import com.mybatisflex.core.keygen.KeyGenerators;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品
|
* 商品
|
||||||
*
|
*
|
||||||
* @author Tankaikai tankaikai@aliyun.com
|
* @author Tankaikai tankaikai@aliyun.com
|
||||||
* @since 1.0 2025-02-10
|
* @since 1.0 2025-02-16
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Table("tb_product")
|
@Table("tb_product")
|
||||||
@@ -26,12 +29,12 @@ public class Product implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* id
|
* id
|
||||||
*/
|
*/
|
||||||
@Id(keyType = KeyType.Auto)
|
@Id(keyType = KeyType.Generator, value = KeyGenerators.snowFlakeId)
|
||||||
private Long id;
|
private Long id;
|
||||||
/**
|
/**
|
||||||
* 商品分类
|
* 商品分类
|
||||||
*/
|
*/
|
||||||
private String categoryId;
|
private Long categoryId;
|
||||||
/**
|
/**
|
||||||
* 商品规格
|
* 商品规格
|
||||||
*/
|
*/
|
||||||
@@ -40,6 +43,9 @@ public class Product implements Serializable {
|
|||||||
* 单位Id
|
* 单位Id
|
||||||
*/
|
*/
|
||||||
private Long unitId;
|
private Long unitId;
|
||||||
|
/**
|
||||||
|
* 店铺id
|
||||||
|
*/
|
||||||
private Long shopId;
|
private Long shopId;
|
||||||
/**
|
/**
|
||||||
* 商品名称
|
* 商品名称
|
||||||
@@ -50,7 +56,7 @@ public class Product implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String shortTitle;
|
private String shortTitle;
|
||||||
/**
|
/**
|
||||||
* 单规格商品 single 多规格商品 sku 套餐商品 package 称重商品 weigh 团购券 coupon
|
* 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券
|
||||||
*/
|
*/
|
||||||
private String type;
|
private String type;
|
||||||
/**
|
/**
|
||||||
@@ -84,7 +90,7 @@ public class Product implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 是否允许临时改价
|
* 是否允许临时改价
|
||||||
*/
|
*/
|
||||||
private Integer isTempPrice;
|
private Integer isAllowTempModifyPrice;
|
||||||
/**
|
/**
|
||||||
* 周 数组 'Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday'
|
* 周 数组 'Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday'
|
||||||
*/
|
*/
|
||||||
@@ -92,11 +98,11 @@ public class Product implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 可用开始时间
|
* 可用开始时间
|
||||||
*/
|
*/
|
||||||
private Object startTime;
|
private LocalTime startTime;
|
||||||
/**
|
/**
|
||||||
* 可用结束时间
|
* 可用结束时间
|
||||||
*/
|
*/
|
||||||
private Object endTime;
|
private LocalTime endTime;
|
||||||
/**
|
/**
|
||||||
* 规格详情
|
* 规格详情
|
||||||
*/
|
*/
|
||||||
@@ -133,7 +139,15 @@ public class Product implements Serializable {
|
|||||||
* 退款是否退回库存
|
* 退款是否退回库存
|
||||||
*/
|
*/
|
||||||
private Integer isRefundStock;
|
private Integer isRefundStock;
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@Column(onInsertValue = "now()")
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@Column(onInsertValue = "now()", onUpdateValue = "now()")
|
||||||
private LocalDateTime updateTime;
|
private LocalDateTime updateTime;
|
||||||
/**
|
/**
|
||||||
* 逻辑删除
|
* 逻辑删除
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.czg.product.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品类型
|
||||||
|
*
|
||||||
|
* @author tankaikai
|
||||||
|
* @since 2025-02-16 15:20
|
||||||
|
*/
|
||||||
|
public enum ProductTypeEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单规格商品
|
||||||
|
*/
|
||||||
|
SINGLE("single"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多规格商品
|
||||||
|
*/
|
||||||
|
SKU("sku"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 套餐商品
|
||||||
|
*/
|
||||||
|
PACKAGE("package"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 称重商品
|
||||||
|
*/
|
||||||
|
WEIGHT("weight"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* coupon
|
||||||
|
*/
|
||||||
|
COUPON("coupon");
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
ProductTypeEnum(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String value() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.czg.product.service;
|
||||||
|
|
||||||
|
import com.czg.product.dto.ProdSkuDTO;
|
||||||
|
import com.czg.product.entity.ProdSku;
|
||||||
|
import com.mybatisflex.core.paginate.Page;
|
||||||
|
import com.mybatisflex.core.service.IService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品SKU
|
||||||
|
*
|
||||||
|
* @author Tankaikai tankaikai@aliyun.com
|
||||||
|
* @since 1.0 2025-02-16
|
||||||
|
*/
|
||||||
|
public interface ProdSkuService extends IService<ProdSku> {
|
||||||
|
Page<ProdSkuDTO> getProdSkuPage(ProdSkuDTO param);
|
||||||
|
|
||||||
|
List<ProdSkuDTO> getProdSkuList(ProdSkuDTO param);
|
||||||
|
|
||||||
|
ProdSkuDTO getProdSkuById(Long id);
|
||||||
|
|
||||||
|
boolean addProdSku(ProdSkuDTO dto);
|
||||||
|
|
||||||
|
boolean deleteProdSku(Long id);
|
||||||
|
|
||||||
|
boolean updateProdSku(ProdSkuDTO dto);
|
||||||
|
|
||||||
|
boolean disableProdSku(Long id);
|
||||||
|
|
||||||
|
boolean enableProdSku(Long id);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,15 +1,33 @@
|
|||||||
package com.czg.product.service;
|
package com.czg.product.service;
|
||||||
|
|
||||||
|
import com.czg.product.dto.ProductDTO;
|
||||||
import com.czg.product.entity.Product;
|
import com.czg.product.entity.Product;
|
||||||
|
import com.mybatisflex.core.paginate.Page;
|
||||||
import com.mybatisflex.core.service.IService;
|
import com.mybatisflex.core.service.IService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品
|
* 商品
|
||||||
*
|
*
|
||||||
* @author Tankaikai tankaikai@aliyun.com
|
* @author Tankaikai tankaikai@aliyun.com
|
||||||
* @since 1.0 2025-02-10
|
* @since 1.0 2025-02-16
|
||||||
*/
|
*/
|
||||||
public interface ProductService extends IService<Product> {
|
public interface ProductService extends IService<Product> {
|
||||||
|
Page<ProductDTO> getProductPage(ProductDTO param);
|
||||||
|
|
||||||
|
List<ProductDTO> getProductList(ProductDTO param);
|
||||||
|
|
||||||
|
ProductDTO getProductById(Long id);
|
||||||
|
|
||||||
|
boolean addProduct(ProductDTO dto);
|
||||||
|
|
||||||
|
boolean deleteProduct(Long id);
|
||||||
|
|
||||||
|
boolean updateProduct(ProductDTO dto);
|
||||||
|
|
||||||
|
boolean disableProduct(Long id);
|
||||||
|
|
||||||
|
boolean enableProduct(Long id);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.czg.product.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ProductGroupVo {
|
||||||
|
|
||||||
|
private Integer count;
|
||||||
|
//选几个
|
||||||
|
private Integer number;
|
||||||
|
//类别
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
//食物
|
||||||
|
private List<Food> goods = new ArrayList<>();
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Food {
|
||||||
|
private Integer proId;
|
||||||
|
private String proName;
|
||||||
|
private Integer skuId;
|
||||||
|
private String skuName;
|
||||||
|
private BigDecimal price;
|
||||||
|
private String number;
|
||||||
|
private String unitName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.czg.service.product.mapper;
|
||||||
|
|
||||||
|
import com.czg.product.entity.ProdSku;
|
||||||
|
import com.mybatisflex.core.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品SKU
|
||||||
|
*
|
||||||
|
* @author Tankaikai tankaikai@aliyun.com
|
||||||
|
* @since 1.0 2025-02-16
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface ProdSkuMapper extends BaseMapper<ProdSku> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ import org.apache.ibatis.annotations.Mapper;
|
|||||||
* 商品
|
* 商品
|
||||||
*
|
*
|
||||||
* @author Tankaikai tankaikai@aliyun.com
|
* @author Tankaikai tankaikai@aliyun.com
|
||||||
* @since 1.0 2025-02-10
|
* @since 1.0 2025-02-16
|
||||||
*/
|
*/
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface ProductMapper extends BaseMapper<Product> {
|
public interface ProductMapper extends BaseMapper<Product> {
|
||||||
|
|||||||
@@ -11,6 +11,6 @@ import org.apache.ibatis.annotations.Mapper;
|
|||||||
* @since 1.0 2025-02-13
|
* @since 1.0 2025-02-13
|
||||||
*/
|
*/
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface ShopProductSpecMapper extends BaseMapper<ShopProdSpec> {
|
public interface ShopProdSpecMapper extends BaseMapper<ShopProdSpec> {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
package com.czg.service.product.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import com.czg.exception.CzgException;
|
||||||
|
import com.czg.product.dto.ProdSkuDTO;
|
||||||
|
import com.czg.product.entity.ProdSku;
|
||||||
|
import com.czg.product.service.ProdSkuService;
|
||||||
|
import com.czg.sa.StpKit;
|
||||||
|
import com.czg.service.product.mapper.ProdSkuMapper;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品SKU
|
||||||
|
*
|
||||||
|
* @author Tankaikai tankaikai@aliyun.com
|
||||||
|
* @since 1.0 2025-02-16
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class ProdSkuServiceImpl extends ServiceImpl<ProdSkuMapper, ProdSku> implements ProdSkuService {
|
||||||
|
|
||||||
|
private QueryWrapper buildQueryWrapper(ProdSkuDTO param) {
|
||||||
|
QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
|
||||||
|
/*if (StrUtil.isNotEmpty(param.getName())) {
|
||||||
|
queryWrapper.like(ProdSku::getName, param.getName());
|
||||||
|
}*/
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
queryWrapper.eq(ProdSku::getShopId, shopId);
|
||||||
|
queryWrapper.orderBy(ProdSku::getId, false);
|
||||||
|
return queryWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<ProdSkuDTO> getProdSkuPage(ProdSkuDTO param) {
|
||||||
|
QueryWrapper queryWrapper = buildQueryWrapper(param);
|
||||||
|
return super.pageAs(PageUtil.buildPage(), queryWrapper, ProdSkuDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ProdSkuDTO> getProdSkuList(ProdSkuDTO param) {
|
||||||
|
QueryWrapper queryWrapper = buildQueryWrapper(param);
|
||||||
|
//queryWrapper.eq(ProdSku::getStatus, StatusEnum.ENABLED.value());
|
||||||
|
return super.listAs(queryWrapper, ProdSkuDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProdSkuDTO getProdSkuById(Long id) {
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
return super.getOneAs(query().eq(ProdSku::getId, id).eq(ProdSku::getShopId, shopId), ProdSkuDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addProdSku(ProdSkuDTO dto) {
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
boolean exists = true;
|
||||||
|
//super.exists(query().eq(ProdSku::getName, dto.getName()).eq(ProdSku::getShopId, shopId));
|
||||||
|
if (exists) {
|
||||||
|
throw new CzgException("商品SKU已存在");
|
||||||
|
}
|
||||||
|
ProdSku entity = BeanUtil.copyProperties(dto, ProdSku.class);
|
||||||
|
//entity.setStatus(StatusEnum.ENABLED.value());
|
||||||
|
entity.setShopId(shopId);
|
||||||
|
return super.save(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateProdSku(ProdSkuDTO dto) {
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
dto.setShopId(shopId);
|
||||||
|
//boolean exists = super.exists(query().eq(ProdSku::getName, dto.getName()).eq(ProdSku::getShopId, shopId).ne(ProdSku::getId, dto.getId()));
|
||||||
|
boolean exists = true;
|
||||||
|
if (exists) {
|
||||||
|
throw new CzgException("商品SKU已存在");
|
||||||
|
}
|
||||||
|
ProdSku entity = BeanUtil.copyProperties(dto, ProdSku.class);
|
||||||
|
return super.updateById(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteProdSku(Long id) {
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
//return super.remove(query().eq(ClassName}::getId, id).eq(ClassName}::getShopId, shopId));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean disableProdSku(Long id) {
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
return UpdateChain.of(ProdSku.class)
|
||||||
|
//.set(ProdSku::getStatus, StatusEnum.DISABLE.value())
|
||||||
|
.eq(ProdSku::getId, id)
|
||||||
|
.eq(ProdSku::getShopId, shopId)
|
||||||
|
.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean enableProdSku(Long id) {
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
return UpdateChain.of(ProdSku.class)
|
||||||
|
//.set(ProdSku::getStatus, StatusEnum.ENABLED.value())
|
||||||
|
.eq(ProdSku::getId, id)
|
||||||
|
.eq(ProdSku::getShopId, shopId)
|
||||||
|
.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,19 +1,174 @@
|
|||||||
package com.czg.service.product.service.impl;
|
package com.czg.service.product.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.czg.enums.DeleteEnum;
|
||||||
|
import com.czg.enums.YesNoEnum;
|
||||||
|
import com.czg.exception.CzgException;
|
||||||
|
import com.czg.product.dto.ProdSkuDTO;
|
||||||
|
import com.czg.product.dto.ProductDTO;
|
||||||
|
import com.czg.product.entity.ProdSku;
|
||||||
import com.czg.product.entity.Product;
|
import com.czg.product.entity.Product;
|
||||||
|
import com.czg.product.enums.ProductTypeEnum;
|
||||||
import com.czg.product.service.ProductService;
|
import com.czg.product.service.ProductService;
|
||||||
|
import com.czg.sa.StpKit;
|
||||||
|
import com.czg.service.product.mapper.ProdSkuMapper;
|
||||||
import com.czg.service.product.mapper.ProductMapper;
|
import com.czg.service.product.mapper.ProductMapper;
|
||||||
|
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 com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.czg.product.entity.table.ProductTableDef.PRODUCT;
|
||||||
|
import static com.czg.product.entity.table.ShopProdCategoryTableDef.SHOP_PROD_CATEGORY;
|
||||||
|
import static com.czg.product.entity.table.ShopProdSpecTableDef.SHOP_PROD_SPEC;
|
||||||
|
import static com.czg.product.entity.table.ShopProdUnitTableDef.SHOP_PROD_UNIT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品
|
* 商品
|
||||||
*
|
*
|
||||||
* @author Tankaikai tankaikai@aliyun.com
|
* @author Tankaikai tankaikai@aliyun.com
|
||||||
* @since 1.0 2025-02-10
|
* @since 1.0 2025-02-16
|
||||||
*/
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
@Service
|
@Service
|
||||||
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
|
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
|
||||||
|
|
||||||
|
private final ProdSkuMapper prodSkuMapper;
|
||||||
|
|
||||||
|
private QueryWrapper buildQueryWrapper(ProductDTO param) {
|
||||||
|
QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
|
||||||
|
if (StrUtil.isNotEmpty(param.getName())) {
|
||||||
|
queryWrapper.like(Product::getName, param.getName());
|
||||||
|
}
|
||||||
|
if (ObjUtil.isNotNull(param.getCategoryId())) {
|
||||||
|
queryWrapper.eq(Product::getCategoryId, param.getCategoryId());
|
||||||
|
}
|
||||||
|
if (ObjUtil.isNotNull(param.getSpecId())) {
|
||||||
|
queryWrapper.like(Product::getSpecId, param.getSpecId());
|
||||||
|
}
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
queryWrapper.eq(Product::getShopId, shopId);
|
||||||
|
queryWrapper.eq(Product::getIsDel, DeleteEnum.NORMAL.value());
|
||||||
|
queryWrapper.orderBy(Product::getSort, false);
|
||||||
|
queryWrapper.orderBy(Product::getId, false);
|
||||||
|
return queryWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<ProductDTO> getProductPage(ProductDTO param) {
|
||||||
|
QueryWrapper queryWrapper = buildQueryWrapper(param);
|
||||||
|
queryWrapper.select(PRODUCT.DEFAULT_COLUMNS)
|
||||||
|
.select(SHOP_PROD_UNIT.NAME.as(ProductDTO::getUnitName))
|
||||||
|
.select(SHOP_PROD_CATEGORY.NAME.as(ProductDTO::getCategoryName))
|
||||||
|
.select(SHOP_PROD_SPEC.NAME.as(ProductDTO::getSpecName),SHOP_PROD_SPEC.FULL_NAME.as(ProductDTO::getSpecFullName))
|
||||||
|
.from(PRODUCT)
|
||||||
|
.leftJoin(SHOP_PROD_UNIT).on(SHOP_PROD_UNIT.ID.eq(PRODUCT.UNIT_ID))
|
||||||
|
.leftJoin(SHOP_PROD_CATEGORY).on(SHOP_PROD_CATEGORY.ID.eq(PRODUCT.CATEGORY_ID))
|
||||||
|
.leftJoin(SHOP_PROD_SPEC).on(SHOP_PROD_SPEC.ID.eq(PRODUCT.SPEC_ID));
|
||||||
|
return super.pageAs(PageUtil.buildPage(), queryWrapper, ProductDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ProductDTO> getProductList(ProductDTO param) {
|
||||||
|
QueryWrapper queryWrapper = buildQueryWrapper(param);
|
||||||
|
//queryWrapper.eq(Product::getStatus, StatusEnum.ENABLED.value());
|
||||||
|
return super.listAs(queryWrapper, ProductDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProductDTO getProductById(Long id) {
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
return super.getOneAs(query().eq(Product::getId, id).eq(Product::getShopId, shopId), ProductDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public boolean addProduct(ProductDTO dto) {
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
boolean exists = super.exists(query().eq(Product::getName, dto.getName()).eq(Product::getShopId, shopId));
|
||||||
|
if (exists) {
|
||||||
|
throw new CzgException("商品已存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
Product entity = BeanUtil.copyProperties(dto, Product.class);
|
||||||
|
//套餐
|
||||||
|
if (ProductTypeEnum.PACKAGE.value().equals(dto.getType())) {
|
||||||
|
//套餐内容
|
||||||
|
if (CollUtil.isNotEmpty(dto.getProGroupVo())) {
|
||||||
|
entity.setGroupSnap(JSON.toJSONString(dto.getProGroupVo()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.setSpecInfo(JSON.toJSONString(dto.getSkuList()));
|
||||||
|
entity.setIsDel(DeleteEnum.NORMAL.value());
|
||||||
|
entity.setShopId(shopId);
|
||||||
|
super.save(entity);
|
||||||
|
List<ProdSkuDTO> skuList = dto.getSkuList();
|
||||||
|
if(CollUtil.isNotEmpty(skuList)){
|
||||||
|
List<ProdSku> prodSkuList = new ArrayList<>();
|
||||||
|
for (ProdSkuDTO prodSkuDTO : skuList) {
|
||||||
|
ProdSku prodSku = BeanUtil.copyProperties(prodSkuDTO, ProdSku.class);
|
||||||
|
prodSku.setShopId(entity.getShopId());
|
||||||
|
prodSku.setProductId(entity.getId());
|
||||||
|
prodSku.setRealSalesNumber(BigDecimal.ZERO);
|
||||||
|
prodSku.setIsPauseSale(YesNoEnum.NO.value());
|
||||||
|
prodSku.setIsGrounding(YesNoEnum.YES.value());
|
||||||
|
prodSku.setIsDel(DeleteEnum.NORMAL.value());
|
||||||
|
prodSkuList.add(prodSku);
|
||||||
|
}
|
||||||
|
prodSkuMapper.insertBatch(prodSkuList);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateProduct(ProductDTO dto) {
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
dto.setShopId(shopId);
|
||||||
|
boolean exists = super.exists(query().eq(Product::getName, dto.getName()).eq(Product::getShopId, shopId).ne(Product::getId, dto.getId()));
|
||||||
|
if (exists) {
|
||||||
|
throw new CzgException("商品已存在");
|
||||||
|
}
|
||||||
|
Product entity = BeanUtil.copyProperties(dto, Product.class);
|
||||||
|
return super.updateById(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteProduct(Long id) {
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
return super.remove(query().eq(Product::getId, id).eq(Product::getShopId, shopId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean disableProduct(Long id) {
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
return UpdateChain.of(Product.class)
|
||||||
|
//.set(Product::getStatus, StatusEnum.DISABLE.value())
|
||||||
|
.eq(Product::getId, id)
|
||||||
|
.eq(Product::getShopId, shopId)
|
||||||
|
.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean enableProduct(Long id) {
|
||||||
|
Long shopId = StpKit.USER.getLoginIdAsLong();
|
||||||
|
return UpdateChain.of(Product.class)
|
||||||
|
//.set(Product::getStatus, StatusEnum.ENABLED.value())
|
||||||
|
.eq(Product::getId, id)
|
||||||
|
.eq(Product::getShopId, shopId)
|
||||||
|
.update();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,7 @@ import com.czg.product.dto.ShopProdSpecDTO;
|
|||||||
import com.czg.product.entity.ShopProdSpec;
|
import com.czg.product.entity.ShopProdSpec;
|
||||||
import com.czg.product.service.ShopProdSpecService;
|
import com.czg.product.service.ShopProdSpecService;
|
||||||
import com.czg.sa.StpKit;
|
import com.czg.sa.StpKit;
|
||||||
import com.czg.service.product.mapper.ShopProductSpecMapper;
|
import com.czg.service.product.mapper.ShopProdSpecMapper;
|
||||||
import com.czg.utils.PageUtil;
|
import com.czg.utils.PageUtil;
|
||||||
import com.czg.utils.TreeUtils;
|
import com.czg.utils.TreeUtils;
|
||||||
import com.mybatisflex.core.paginate.Page;
|
import com.mybatisflex.core.paginate.Page;
|
||||||
@@ -31,7 +31,7 @@ import static com.czg.product.entity.table.ShopProdSpecTableDef.SHOP_PROD_SPEC;
|
|||||||
* @since 1.0 2025-02-13
|
* @since 1.0 2025-02-13
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class ShopProductSpecServiceImpl extends ServiceImpl<ShopProductSpecMapper, ShopProdSpec> implements ShopProdSpecService {
|
public class ShopProductSpecServiceImpl extends ServiceImpl<ShopProdSpecMapper, ShopProdSpec> implements ShopProdSpecService {
|
||||||
|
|
||||||
|
|
||||||
private QueryWrapper buildQueryWrapper(ShopProdSpecDTO param) {
|
private QueryWrapper buildQueryWrapper(ShopProdSpecDTO param) {
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
|
<mapper namespace="com.czg.service.product.mapper.ProdSkuMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
|
<mapper namespace="com.czg.service.product.mapper.ShopProdSpecMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
Reference in New Issue
Block a user