!168 增加商品批发销售模式的处理。优化生成商品sku的结构。
Merge pull request !168 from OceansDeep/feature/pg
This commit is contained in:
		
						commit
						8fbcad8856
					
				| @ -1,7 +1,10 @@ | ||||
| /** 增加签到日期 **/ | ||||
| ALTER TABLE li_member_sign ADD day int DEFAULT NULL COMMENT '签到日 '; | ||||
| ALTER TABLE li_member_sign DROP INDEX uk_member_day; | ||||
| ALTER TABLE li_member_sign add unique uk_member_day (member_id, day) COMMENT 'uk_member_day'; | ||||
| ALTER TABLE li_member_sign | ||||
|     ADD day int DEFAULT NULL COMMENT '签到日 '; | ||||
| ALTER TABLE li_member_sign | ||||
|     DROP INDEX uk_member_day; | ||||
| ALTER TABLE li_member_sign | ||||
|     add unique uk_member_day (member_id, day) COMMENT 'uk_member_day'; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -9,10 +12,35 @@ ALTER TABLE li_member_sign add unique uk_member_day (member_id, day) COMMENT 'uk | ||||
| -- Table structure for li_hot_words_history | ||||
| -- ---------------------------- | ||||
| DROP TABLE IF EXISTS `li_hot_words_history`; | ||||
| CREATE TABLE `li_hot_words_history` ( | ||||
| CREATE TABLE `li_hot_words_history` | ||||
| ( | ||||
|     `id`          bigint NOT NULL COMMENT 'ID', | ||||
|     `create_time` datetime(6)                   DEFAULT NULL COMMENT '创建时间', | ||||
|     `keywords`    varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '热词', | ||||
|     `score`       int                           DEFAULT NULL COMMENT '热词分数', | ||||
|     PRIMARY KEY (`id`) | ||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; | ||||
| ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb3 COLLATE = utf8_bin COMMENT '热词历史表'; | ||||
| 
 | ||||
| -- ---------------------------- | ||||
| -- Records of li_hot_words_history | ||||
| -- ---------------------------- | ||||
| 
 | ||||
| -- ---------------------------- | ||||
| -- Table structure for li_wholesale | ||||
| -- ---------------------------- | ||||
| DROP TABLE IF EXISTS `li_wholesale`; | ||||
| CREATE TABLE `li_wholesale` | ||||
| ( | ||||
|     `id`          bigint NOT NULL, | ||||
|     `create_by`   varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, | ||||
|     `create_time` datetime(6)                                            DEFAULT NULL, | ||||
|     `delete_flag` bit(1)                                                 DEFAULT NULL, | ||||
|     `update_by`   varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, | ||||
|     `update_time` datetime(6)                                            DEFAULT NULL, | ||||
|     `price`       decimal(10, 2)                                         DEFAULT NULL COMMENT '价格', | ||||
|     `goods_id`    bigint                                                 DEFAULT NULL COMMENT '商品id', | ||||
|     `sku_id`      bigint                                                 DEFAULT NULL COMMENT '商品skuId', | ||||
|     `num`         int                                                    DEFAULT NULL COMMENT '起购量', | ||||
|     PRIMARY KEY (`id`) | ||||
| ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_bin COMMENT '批发规则表'; | ||||
| 
 | ||||
|  | ||||
| @ -76,6 +76,10 @@ public enum ResultCode { | ||||
|     GOODS_SKU_QUANTITY_ERROR(11011, "商品库存数量不能为负数"), | ||||
|     GOODS_SKU_QUANTITY_NOT_ENOUGH(11011, "商品库存不足"), | ||||
|     MUST_HAVE_GOODS_SKU(11012, "规格必须要有一个!"), | ||||
|     MUST_HAVE_SALES_MODEL(11022, "销售模式为批发时必须要有批发规则!"), | ||||
| 
 | ||||
|     HAVE_INVALID_SALES_MODEL(11023, "批发规则存在小于等于0的无效数据!"), | ||||
| 
 | ||||
|     GOODS_PARAMS_ERROR(11013, "商品参数错误,刷新后重试"), | ||||
|     PHYSICAL_GOODS_NEED_TEMP(11014, "实物商品需选择配送模板"), | ||||
|     VIRTUAL_GOODS_NOT_NEED_TEMP(11015, "虚拟商品无需选择配送模板"), | ||||
|  | ||||
| @ -12,7 +12,6 @@ import lombok.AllArgsConstructor; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import lombok.NoArgsConstructor; | ||||
| import org.hibernate.validator.constraints.Length; | ||||
| 
 | ||||
| import javax.validation.constraints.Max; | ||||
| 
 | ||||
| @ -114,6 +113,9 @@ public class DraftGoods extends BaseEntity { | ||||
|     @ApiModelProperty(value = "是否为推荐商品") | ||||
|     private boolean recommend; | ||||
| 
 | ||||
|     /** | ||||
|      * @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum | ||||
|      */ | ||||
|     @ApiModelProperty(value = "销售模式") | ||||
|     private String salesModel; | ||||
| 
 | ||||
|  | ||||
| @ -8,6 +8,7 @@ import cn.lili.common.enums.ResultCode; | ||||
| import cn.lili.common.exception.ServiceException; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsOperationDTO; | ||||
| import cn.lili.modules.goods.entity.enums.GoodsAuthEnum; | ||||
| import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum; | ||||
| import cn.lili.modules.goods.entity.enums.GoodsStatusEnum; | ||||
| import cn.lili.modules.goods.entity.enums.GoodsTypeEnum; | ||||
| import cn.lili.mybatis.BaseEntity; | ||||
| @ -133,6 +134,9 @@ public class Goods extends BaseEntity { | ||||
|     @ApiModelProperty(value = "是否为推荐商品", required = true) | ||||
|     private Boolean recommend; | ||||
| 
 | ||||
|     /** | ||||
|      * @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum | ||||
|      */ | ||||
|     @ApiModelProperty(value = "销售模式", required = true) | ||||
|     private String salesModel; | ||||
| 
 | ||||
| @ -179,10 +183,10 @@ public class Goods extends BaseEntity { | ||||
|             if (!sku.containsKey("sn") || sku.get("sn") == null) { | ||||
|                 throw new ServiceException(ResultCode.GOODS_SKU_SN_ERROR); | ||||
|             } | ||||
|             if (!sku.containsKey("price") || StringUtil.isEmpty(sku.get("price").toString()) || Convert.toDouble(sku.get("price")) <= 0) { | ||||
|             if ((!sku.containsKey("price") || StringUtil.isEmpty(sku.get("price").toString()) || Convert.toDouble(sku.get("price")) <= 0) && !goodsOperationDTO.getSalesModel().equals(GoodsSalesModeEnum.WHOLESALE.name())) { | ||||
|                 throw new ServiceException(ResultCode.GOODS_SKU_PRICE_ERROR); | ||||
|             } | ||||
|             if (!sku.containsKey("cost") || StringUtil.isEmpty(sku.get("cost").toString()) || Convert.toDouble(sku.get("cost")) <= 0) { | ||||
|             if ((!sku.containsKey("cost") || StringUtil.isEmpty(sku.get("cost").toString()) || Convert.toDouble(sku.get("cost")) <= 0) && !goodsOperationDTO.getSalesModel().equals(GoodsSalesModeEnum.WHOLESALE.name())) { | ||||
|                 throw new ServiceException(ResultCode.GOODS_SKU_COST_ERROR); | ||||
|             } | ||||
|             //虚拟商品没有重量字段 | ||||
|  | ||||
| @ -9,6 +9,7 @@ import io.swagger.annotations.ApiModel; | ||||
| import io.swagger.annotations.ApiModelProperty; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import lombok.NoArgsConstructor; | ||||
| import org.hibernate.validator.constraints.Length; | ||||
| 
 | ||||
| import javax.validation.constraints.Max; | ||||
| @ -24,6 +25,7 @@ import java.util.Date; | ||||
| @Data | ||||
| @TableName("li_goods_sku") | ||||
| @ApiModel(value = "商品sku对象") | ||||
| @NoArgsConstructor | ||||
| public class GoodsSku extends BaseEntity { | ||||
| 
 | ||||
|     private static final long serialVersionUID = 4865908658161118934L; | ||||
| @ -150,6 +152,9 @@ public class GoodsSku extends BaseEntity { | ||||
|     @ApiModelProperty(value = "是否为推荐商品", required = true) | ||||
|     private Boolean recommend; | ||||
| 
 | ||||
|     /** | ||||
|      * @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum | ||||
|      */ | ||||
|     @ApiModelProperty(value = "销售模式", required = true) | ||||
|     private String salesModel; | ||||
|     /** | ||||
| @ -173,4 +178,36 @@ public class GoodsSku extends BaseEntity { | ||||
|             return super.getUpdateTime(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 设置规格商品的基本商品信息 | ||||
|      * | ||||
|      * @param goods 基本商品信息 | ||||
|      */ | ||||
|     public GoodsSku(Goods goods) { | ||||
|         //商品基本信息 | ||||
|         this.goodsId = goods.getId(); | ||||
|         this.goodsName = goods.getGoodsName(); | ||||
|         this.goodsType = goods.getGoodsType(); | ||||
| 
 | ||||
|         this.selfOperated = goods.getSelfOperated(); | ||||
|         this.sellingPoint = goods.getSellingPoint(); | ||||
|         this.categoryPath = goods.getCategoryPath(); | ||||
|         this.brandId = goods.getBrandId(); | ||||
|         this.marketEnable = goods.getMarketEnable(); | ||||
|         this.intro = goods.getIntro(); | ||||
|         this.mobileIntro = goods.getMobileIntro(); | ||||
|         this.goodsUnit = goods.getGoodsUnit(); | ||||
|         this.grade = 100D; | ||||
|         //商品状态 | ||||
|         this.authFlag = goods.getAuthFlag(); | ||||
|         this.salesModel = goods.getSalesModel(); | ||||
|         //卖家信息 | ||||
|         this.storeId = goods.getStoreId(); | ||||
|         this.storeName = goods.getStoreName(); | ||||
|         this.storeCategoryPath = goods.getStoreCategoryPath(); | ||||
|         this.freightTemplateId = goods.getTemplateId(); | ||||
|         this.recommend = goods.getRecommend(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import io.swagger.annotations.ApiModel; | ||||
| import io.swagger.annotations.ApiModelProperty; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import lombok.NoArgsConstructor; | ||||
| 
 | ||||
| 
 | ||||
| @ -15,11 +16,14 @@ import lombok.NoArgsConstructor; | ||||
|  * @since 2021/5/18 5:42 下午 | ||||
|  */ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @ApiModel(value = "直播间商品") | ||||
| @TableName("li_studio_commodity") | ||||
| @NoArgsConstructor | ||||
| public class StudioCommodity extends BaseIdEntity { | ||||
| 
 | ||||
|     private static final long serialVersionUID = 8383627725577840261L; | ||||
| 
 | ||||
|     @ApiModelProperty(value = "房间ID") | ||||
|     private Integer roomId; | ||||
| 
 | ||||
|  | ||||
| @ -0,0 +1,30 @@ | ||||
| package cn.lili.modules.goods.entity.dos; | ||||
| 
 | ||||
| import cn.lili.mybatis.BaseIdEntity; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import io.swagger.annotations.ApiModel; | ||||
| import io.swagger.annotations.ApiModelProperty; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| 
 | ||||
| /** | ||||
|  * @author paulG | ||||
|  * @since 2022/5/20 | ||||
|  **/ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @TableName("li_wholesale") | ||||
| @ApiModel(value = "批发商品") | ||||
| public class Wholesale extends BaseIdEntity { | ||||
| 
 | ||||
|     private static final long serialVersionUID = -6389806138583086068L; | ||||
| 
 | ||||
|     @ApiModelProperty(value = "商品ID") | ||||
|     private String goodsId; | ||||
|     @ApiModelProperty(value = "SkuID") | ||||
|     private String skuId; | ||||
|     @ApiModelProperty(value = "数量") | ||||
|     private Integer num; | ||||
|     @ApiModelProperty(value = "金额") | ||||
|     private Double price; | ||||
| } | ||||
| @ -13,7 +13,7 @@ import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 商品编辑DTO | ||||
|  * 商品操作DTO | ||||
|  * | ||||
|  * @author pikachu | ||||
|  * @since 2020-02-24 19:27:20 | ||||
| @ -77,13 +77,12 @@ public class GoodsOperationDTO implements Serializable { | ||||
|     @Min(value = 0, message = "运费模板值不正确") | ||||
|     private String templateId; | ||||
| 
 | ||||
|     @ApiModelProperty(value = "sku列表") | ||||
|     @Valid | ||||
|     private List<Map<String, Object>> skuList; | ||||
| 
 | ||||
|     @ApiModelProperty(value = "卖点") | ||||
|     private String sellingPoint; | ||||
| 
 | ||||
|     /** | ||||
|      * @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum | ||||
|      */ | ||||
|     @ApiModelProperty(value = "销售模式", required = true) | ||||
|     private String salesModel; | ||||
| 
 | ||||
| @ -112,6 +111,17 @@ public class GoodsOperationDTO implements Serializable { | ||||
|     @ApiModelProperty(value = "商品视频") | ||||
|     private String goodsVideo; | ||||
| 
 | ||||
| 
 | ||||
|     @ApiModelProperty(value = "sku列表") | ||||
|     @Valid | ||||
|     private List<Map<String, Object>> skuList; | ||||
| 
 | ||||
|     /** | ||||
|      * 批发商品规则 | ||||
|      */ | ||||
|     @ApiModelProperty(value = "批发商品规则") | ||||
|     private List<WholesaleDTO> wholesaleList; | ||||
| 
 | ||||
|     public String getGoodsName() { | ||||
|         //对商品对名称做一个极限处理。这里没有用xss过滤是因为xss过滤为全局过滤,影响很大。 | ||||
|         // 业务中,全局代码中只有商品名称不能拥有英文逗号,是由于商品名称存在一个数据库联合查询,结果要根据逗号分组 | ||||
|  | ||||
| @ -77,6 +77,12 @@ public class GoodsSearchParams extends PageVO { | ||||
|     @ApiModelProperty(value = "商品类型") | ||||
|     private String goodsType; | ||||
| 
 | ||||
|     /** | ||||
|      * @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum | ||||
|      */ | ||||
|     @ApiModelProperty(value = "销售模式", required = true) | ||||
|     private String salesModel; | ||||
| 
 | ||||
|     public <T> QueryWrapper<T> queryWrapper() { | ||||
|         QueryWrapper<T> queryWrapper = new QueryWrapper<>(); | ||||
|         if (CharSequenceUtil.isNotEmpty(goodsId)) { | ||||
| @ -121,6 +127,9 @@ public class GoodsSearchParams extends PageVO { | ||||
|         if (CharSequenceUtil.isNotEmpty(goodsType)) { | ||||
|             queryWrapper.eq("goods_type", goodsType); | ||||
|         } | ||||
|         if (CharSequenceUtil.isNotEmpty(salesModel)) { | ||||
|             queryWrapper.eq("sales_model", salesModel); | ||||
|         } | ||||
| 
 | ||||
|         queryWrapper.eq("delete_flag", false); | ||||
|         this.betweenWrapper(queryWrapper); | ||||
|  | ||||
| @ -0,0 +1,16 @@ | ||||
| package cn.lili.modules.goods.entity.dto; | ||||
| 
 | ||||
| import cn.lili.modules.goods.entity.dos.Wholesale; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| 
 | ||||
| /** | ||||
|  * @author paulG | ||||
|  * @since 2022/5/25 | ||||
|  **/ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| public class WholesaleDTO extends Wholesale { | ||||
|     private static final long serialVersionUID = 853297561151783335L; | ||||
| 
 | ||||
| } | ||||
| @ -1,19 +1,14 @@ | ||||
| package cn.lili.modules.goods.entity.enums; | ||||
| 
 | ||||
| /** | ||||
|  * 商品审核 | ||||
|  * 销售模式 | ||||
|  * | ||||
|  * @author pikachu | ||||
|  * @since 2020-02-26 23:24:13 | ||||
|  */ | ||||
| public enum GoodsSalesModeEnum { | ||||
|     /** | ||||
|      * 需要审核 并且待审核 | ||||
|      */ | ||||
| 
 | ||||
|     RETAIL("零售"), | ||||
|     /** | ||||
|      * 审核通过 | ||||
|      */ | ||||
|     WHOLESALE("批发"); | ||||
| 
 | ||||
|     private final String description; | ||||
|  | ||||
| @ -1,9 +1,11 @@ | ||||
| package cn.lili.modules.goods.entity.vos; | ||||
| 
 | ||||
| import cn.lili.modules.goods.entity.dos.Goods; | ||||
| import cn.lili.modules.goods.entity.dos.Wholesale; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsParamsDTO; | ||||
| import io.swagger.annotations.ApiModelProperty; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| @ -14,6 +16,7 @@ import java.util.List; | ||||
|  * @since 2020-02-26 23:24:13 | ||||
|  */ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| public class GoodsVO extends Goods { | ||||
| 
 | ||||
|     private static final long serialVersionUID = 6377623919990713567L; | ||||
| @ -29,4 +32,7 @@ public class GoodsVO extends Goods { | ||||
| 
 | ||||
|     @ApiModelProperty(value = "sku列表") | ||||
|     private List<GoodsSkuVO> skuList; | ||||
| 
 | ||||
|     @ApiModelProperty(value = "批发商品消费规则列表") | ||||
|     private List<Wholesale> wholesaleList; | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,11 @@ | ||||
| package cn.lili.modules.goods.mapper; | ||||
| 
 | ||||
| import cn.lili.modules.goods.entity.dos.Wholesale; | ||||
| import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||||
| 
 | ||||
| /** | ||||
|  * @author paulG | ||||
|  * @since 2022/5/24 | ||||
|  **/ | ||||
| public interface WholesaleMapper extends BaseMapper<Wholesale> { | ||||
| } | ||||
| @ -0,0 +1,19 @@ | ||||
| package cn.lili.modules.goods.render; | ||||
| 
 | ||||
| import cn.lili.modules.goods.entity.dos.GoodsSku; | ||||
| 
 | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 商品sku渲染器 | ||||
|  * | ||||
|  * @author paulG | ||||
|  * @since 2022/5/20 | ||||
|  **/ | ||||
| public interface GoodsSkuRender { | ||||
| 
 | ||||
| 
 | ||||
|     GoodsSku render(List<Map<String, Object>> skuList); | ||||
| 
 | ||||
| } | ||||
| @ -3,6 +3,7 @@ package cn.lili.modules.goods.service; | ||||
| import cn.lili.cache.CachePrefix; | ||||
| import cn.lili.modules.goods.entity.dos.Goods; | ||||
| import cn.lili.modules.goods.entity.dos.GoodsSku; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsOperationDTO; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsSearchParams; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsSkuStockDTO; | ||||
| import cn.lili.modules.goods.entity.vos.GoodsSkuVO; | ||||
| @ -43,19 +44,18 @@ public interface GoodsSkuService extends IService<GoodsSku> { | ||||
|     /** | ||||
|      * 添加商品sku | ||||
|      * | ||||
|      * @param skuList sku列表 | ||||
|      * @param goods             商品信息 | ||||
|      * @param goodsOperationDTO 商品操作信息 | ||||
|      */ | ||||
|     void add(List<Map<String, Object>> skuList, Goods goods); | ||||
|     void add(Goods goods, GoodsOperationDTO goodsOperationDTO); | ||||
| 
 | ||||
|     /** | ||||
|      * 更新商品sku | ||||
|      * | ||||
|      * @param skuList            sku列表 | ||||
|      * @param goods             商品信息 | ||||
|      * @param regeneratorSkuFlag 是否是否重新生成sku | ||||
|      * @param goodsOperationDTO 商品操作信息 | ||||
|      */ | ||||
|     void update(List<Map<String, Object>> skuList, Goods goods, Boolean regeneratorSkuFlag); | ||||
|     void update(Goods goods, GoodsOperationDTO goodsOperationDTO); | ||||
| 
 | ||||
|     /** | ||||
|      * 更新商品sku | ||||
|  | ||||
| @ -0,0 +1,28 @@ | ||||
| package cn.lili.modules.goods.service; | ||||
| 
 | ||||
| import cn.lili.modules.goods.entity.dos.Wholesale; | ||||
| import com.baomidou.mybatisplus.extension.service.IService; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * @author paulG | ||||
|  * @since 2022/5/24 | ||||
|  **/ | ||||
| public interface WholesaleService extends IService<Wholesale> { | ||||
| 
 | ||||
| 
 | ||||
|     List<Wholesale> findByGoodsId(String goodsId); | ||||
| 
 | ||||
|     Boolean removeByGoodsId(String goodsId); | ||||
| 
 | ||||
|     /** | ||||
|      * 匹配批发规则 | ||||
|      * | ||||
|      * @param goodsId 商品规则 | ||||
|      * @param num 数量 | ||||
|      * @return 批发规则 | ||||
|      */ | ||||
|     Wholesale match(String goodsId, Integer num); | ||||
| 
 | ||||
| } | ||||
| @ -1,5 +1,6 @@ | ||||
| package cn.lili.modules.goods.serviceimpl; | ||||
| 
 | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.text.CharSequenceUtil; | ||||
| import cn.hutool.core.util.NumberUtil; | ||||
| import cn.hutool.json.JSONUtil; | ||||
| @ -14,6 +15,7 @@ import cn.lili.common.security.enums.UserEnums; | ||||
| import cn.lili.modules.goods.entity.dos.Category; | ||||
| import cn.lili.modules.goods.entity.dos.Goods; | ||||
| import cn.lili.modules.goods.entity.dos.GoodsGallery; | ||||
| import cn.lili.modules.goods.entity.dos.Wholesale; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsOperationDTO; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsParamsDTO; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsSearchParams; | ||||
| @ -22,10 +24,7 @@ import cn.lili.modules.goods.entity.enums.GoodsStatusEnum; | ||||
| import cn.lili.modules.goods.entity.vos.GoodsSkuVO; | ||||
| import cn.lili.modules.goods.entity.vos.GoodsVO; | ||||
| import cn.lili.modules.goods.mapper.GoodsMapper; | ||||
| import cn.lili.modules.goods.service.CategoryService; | ||||
| import cn.lili.modules.goods.service.GoodsGalleryService; | ||||
| import cn.lili.modules.goods.service.GoodsService; | ||||
| import cn.lili.modules.goods.service.GoodsSkuService; | ||||
| import cn.lili.modules.goods.service.*; | ||||
| import cn.lili.modules.member.entity.dos.MemberEvaluation; | ||||
| import cn.lili.modules.member.entity.enums.EvaluationGradeEnum; | ||||
| import cn.lili.modules.member.service.MemberEvaluationService; | ||||
| @ -110,6 +109,9 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements | ||||
|     @Autowired | ||||
|     private FreightTemplateService freightTemplateService; | ||||
| 
 | ||||
|     @Autowired | ||||
|     private WholesaleService wholesaleService; | ||||
| 
 | ||||
|     @Autowired | ||||
|     private Cache<GoodsVO> cache; | ||||
| 
 | ||||
| @ -168,7 +170,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements | ||||
|         //添加商品 | ||||
|         this.save(goods); | ||||
|         //添加商品sku信息 | ||||
|         this.goodsSkuService.add(goodsOperationDTO.getSkuList(), goods); | ||||
|         this.goodsSkuService.add(goods, goodsOperationDTO); | ||||
|         //添加相册 | ||||
|         if (goodsOperationDTO.getGoodsGalleryList() != null && !goodsOperationDTO.getGoodsGalleryList().isEmpty()) { | ||||
|             this.goodsGalleryService.add(goodsOperationDTO.getGoodsGalleryList(), goods.getId()); | ||||
| @ -192,7 +194,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements | ||||
|         //修改商品 | ||||
|         this.updateById(goods); | ||||
|         //修改商品sku信息 | ||||
|         this.goodsSkuService.update(goodsOperationDTO.getSkuList(), goods, goodsOperationDTO.getRegeneratorSkuFlag()); | ||||
|         this.goodsSkuService.update(goods, goodsOperationDTO); | ||||
|         //添加相册 | ||||
|         if (goodsOperationDTO.getGoodsGalleryList() != null && !goodsOperationDTO.getGoodsGalleryList().isEmpty()) { | ||||
|             this.goodsGalleryService.add(goodsOperationDTO.getGoodsGalleryList(), goods.getId()); | ||||
| @ -247,6 +249,12 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements | ||||
|         if (CharSequenceUtil.isNotEmpty(goods.getParams())) { | ||||
|             goodsVO.setGoodsParamsDTOList(JSONUtil.toList(goods.getParams(), GoodsParamsDTO.class)); | ||||
|         } | ||||
| 
 | ||||
|         List<Wholesale> wholesaleList = wholesaleService.findByGoodsId(goodsId); | ||||
|         if (CollUtil.isNotEmpty(wholesaleList)) { | ||||
|             goodsVO.setWholesaleList(wholesaleList); | ||||
|         } | ||||
| 
 | ||||
|         cache.put(CachePrefix.GOODS.getPrefix() + goodsId, goodsVO); | ||||
|         return goodsVO; | ||||
|     } | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| package cn.lili.modules.goods.serviceimpl; | ||||
| 
 | ||||
| import cn.hutool.core.convert.Convert; | ||||
| import cn.hutool.core.map.MapUtil; | ||||
| import cn.hutool.core.text.CharSequenceUtil; | ||||
| import cn.hutool.core.util.NumberUtil; | ||||
| @ -16,6 +15,7 @@ import cn.lili.common.security.context.UserContext; | ||||
| import cn.lili.common.utils.SnowFlake; | ||||
| import cn.lili.modules.goods.entity.dos.Goods; | ||||
| import cn.lili.modules.goods.entity.dos.GoodsSku; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsOperationDTO; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsSearchParams; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsSkuStockDTO; | ||||
| import cn.lili.modules.goods.entity.enums.GoodsAuthEnum; | ||||
| @ -26,10 +26,9 @@ import cn.lili.modules.goods.entity.vos.GoodsVO; | ||||
| import cn.lili.modules.goods.entity.vos.SpecValueVO; | ||||
| import cn.lili.modules.goods.event.GeneratorEsGoodsIndexEvent; | ||||
| import cn.lili.modules.goods.mapper.GoodsSkuMapper; | ||||
| import cn.lili.modules.goods.service.CategoryService; | ||||
| import cn.lili.modules.goods.service.GoodsGalleryService; | ||||
| import cn.lili.modules.goods.service.GoodsService; | ||||
| import cn.lili.modules.goods.service.GoodsSkuService; | ||||
| import cn.lili.modules.goods.service.*; | ||||
| import cn.lili.modules.goods.sku.GoodsSkuBuilder; | ||||
| import cn.lili.modules.goods.sku.render.SalesModelRender; | ||||
| import cn.lili.modules.member.entity.dos.FootPrint; | ||||
| import cn.lili.modules.member.entity.dto.EvaluationQueryParams; | ||||
| import cn.lili.modules.member.entity.enums.EvaluationGradeEnum; | ||||
| @ -38,7 +37,6 @@ import cn.lili.modules.promotion.entity.dos.PromotionGoods; | ||||
| import cn.lili.modules.promotion.entity.dto.search.PromotionGoodsSearchParams; | ||||
| import cn.lili.modules.promotion.entity.enums.CouponGetEnum; | ||||
| import cn.lili.modules.promotion.service.PromotionGoodsService; | ||||
| import cn.lili.modules.search.entity.dos.EsGoodsAttribute; | ||||
| import cn.lili.modules.search.entity.dos.EsGoodsIndex; | ||||
| import cn.lili.modules.search.service.EsGoodsIndexService; | ||||
| import cn.lili.modules.search.utils.EsIndexUtil; | ||||
| @ -114,35 +112,42 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i | ||||
|     @Autowired | ||||
|     private ApplicationEventPublisher applicationEventPublisher; | ||||
| 
 | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void add(List<Map<String, Object>> skuList, Goods goods) { | ||||
|         // 检查是否需要生成索引 | ||||
|         List<GoodsSku> newSkuList; | ||||
|         //如果有规格 | ||||
|         if (skuList != null && !skuList.isEmpty()) { | ||||
|             // 添加商品sku | ||||
|             newSkuList = this.addGoodsSku(skuList, goods); | ||||
|         } else { | ||||
|             throw new ServiceException(ResultCode.MUST_HAVE_GOODS_SKU); | ||||
|         } | ||||
|     @Autowired | ||||
|     private WholesaleService wholesaleService; | ||||
| 
 | ||||
|         this.updateStock(newSkuList); | ||||
|         if (!newSkuList.isEmpty()) { | ||||
|             generateEs(goods); | ||||
|         } | ||||
|     } | ||||
|     @Autowired | ||||
|     private List<SalesModelRender> salesModelRenders; | ||||
| 
 | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void update(List<Map<String, Object>> skuList, Goods goods, Boolean regeneratorSkuFlag) { | ||||
|     public void add(Goods goods, GoodsOperationDTO goodsOperationDTO) { | ||||
|         // 是否存在规格 | ||||
|         if (skuList == null || skuList.isEmpty()) { | ||||
|         if (goodsOperationDTO.getSkuList() == null || goodsOperationDTO.getSkuList().isEmpty()) { | ||||
|             throw new ServiceException(ResultCode.MUST_HAVE_GOODS_SKU); | ||||
|         } | ||||
|         List<GoodsSku> newSkuList; | ||||
|         // 检查是否需要生成索引 | ||||
|         List<GoodsSku> goodsSkus = GoodsSkuBuilder.buildBatch(goods, goodsOperationDTO); | ||||
|         renderGoodsSkuList(goodsSkus, goodsOperationDTO); | ||||
| 
 | ||||
|         if (!goodsSkus.isEmpty()) { | ||||
|             this.saveOrUpdateBatch(goodsSkus); | ||||
|             this.updateStock(goodsSkus); | ||||
|             this.generateEs(goods); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void update(Goods goods, GoodsOperationDTO goodsOperationDTO) { | ||||
|         // 是否存在规格 | ||||
|         if (goodsOperationDTO.getSkuList() == null || goodsOperationDTO.getSkuList().isEmpty()) { | ||||
|             throw new ServiceException(ResultCode.MUST_HAVE_GOODS_SKU); | ||||
|         } | ||||
|         List<GoodsSku> skuList; | ||||
|         //删除旧的sku信息 | ||||
|         if (Boolean.TRUE.equals(regeneratorSkuFlag)) { | ||||
|         if (Boolean.TRUE.equals(goodsOperationDTO.getRegeneratorSkuFlag())) { | ||||
|             skuList = GoodsSkuBuilder.buildBatch(goods, goodsOperationDTO); | ||||
|             renderGoodsSkuList(skuList, goodsOperationDTO); | ||||
|             List<GoodsSkuVO> goodsListByGoodsId = getGoodsListByGoodsId(goods.getId()); | ||||
|             List<String> oldSkuIds = new ArrayList<>(); | ||||
|             //删除旧索引 | ||||
| @ -154,40 +159,34 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i | ||||
|             this.remove(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getId())); | ||||
|             //删除sku相册 | ||||
|             goodsGalleryService.removeByGoodsId(goods.getId()); | ||||
|             getGoodsListByGoodsId(goods.getId()); | ||||
|             // 添加商品sku | ||||
|             newSkuList = this.addGoodsSku(skuList, goods); | ||||
| 
 | ||||
|             //发送mq消息 | ||||
|             String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.SKU_DELETE.name(); | ||||
|             rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(oldSkuIds), RocketmqSendCallbackBuilder.commonCallback()); | ||||
|         } else { | ||||
|             newSkuList = new ArrayList<>(); | ||||
|             for (Map<String, Object> map : skuList) { | ||||
|             skuList = new ArrayList<>(); | ||||
|             for (Map<String, Object> map : goodsOperationDTO.getSkuList()) { | ||||
|                 GoodsSku sku = null; | ||||
|                 if (map.get("id") != null) { | ||||
|                     sku = this.getGoodsSkuByIdFromCache(map.get("id").toString()); | ||||
|                     sku = GoodsSkuBuilder.build(this.getGoodsSkuByIdFromCache(map.get("id").toString()), map, goodsOperationDTO); | ||||
|                 } | ||||
|                 if (sku == null || map.get("id") == null) { | ||||
|                     sku = new GoodsSku(); | ||||
|                     sku = GoodsSkuBuilder.build(goods, map, goodsOperationDTO); | ||||
|                 } | ||||
|                 //设置商品信息 | ||||
|                 goodsInfo(sku, goods); | ||||
|                 //设置商品规格信息 | ||||
|                 skuInfo(sku, goods, map, null); | ||||
|                 newSkuList.add(sku); | ||||
|                 renderGoodsSku(sku, goodsOperationDTO); | ||||
|                 skuList.add(sku); | ||||
|                 //如果商品状态值不对,则es索引移除 | ||||
|                 if (goods.getAuthFlag().equals(GoodsAuthEnum.PASS.name()) && goods.getMarketEnable().equals(GoodsStatusEnum.UPPER.name())) { | ||||
|                     goodsIndexService.deleteIndexById(sku.getId()); | ||||
|                     this.clearCache(sku.getId()); | ||||
|                 } | ||||
|             } | ||||
|             this.remove(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getId())); | ||||
|             this.saveOrUpdateBatch(newSkuList); | ||||
|         } | ||||
|         this.updateStock(newSkuList); | ||||
|         if (GoodsAuthEnum.PASS.name().equals(goods.getAuthFlag()) && !newSkuList.isEmpty()) { | ||||
|             generateEs(goods); | ||||
|         if (!skuList.isEmpty()) { | ||||
|             this.remove(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getId())); | ||||
|             this.saveOrUpdateBatch(skuList); | ||||
|             this.updateStock(skuList); | ||||
|             this.generateEs(goods); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -257,9 +256,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i | ||||
|         } | ||||
| 
 | ||||
|         //商品下架||商品未审核通过||商品删除,则提示:商品已下架 | ||||
|         if (GoodsStatusEnum.DOWN.name().equals(goodsVO.getMarketEnable()) | ||||
|                 || !GoodsAuthEnum.PASS.name().equals(goodsVO.getAuthFlag()) | ||||
|                 || Boolean.TRUE.equals(goodsVO.getDeleteFlag())) { | ||||
|         if (GoodsStatusEnum.DOWN.name().equals(goodsVO.getMarketEnable()) || !GoodsAuthEnum.PASS.name().equals(goodsVO.getAuthFlag()) || Boolean.TRUE.equals(goodsVO.getDeleteFlag())) { | ||||
|             throw new ServiceException(ResultCode.GOODS_NOT_EXIST); | ||||
|         } | ||||
| 
 | ||||
| @ -278,13 +275,10 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i | ||||
|             promotionMap = promotionMap.entrySet().stream().parallel().filter(i -> { | ||||
|                 JSONObject jsonObject = JSONUtil.parseObj(i.getValue()); | ||||
|                 // 过滤活动赠送优惠券和无效时间的活动 | ||||
|                 return (jsonObject.get("getType") == null || jsonObject.get("getType", String.class).equals(CouponGetEnum.FREE.name())) && | ||||
|                         (jsonObject.get("startTime") != null && jsonObject.get("startTime", Date.class).getTime() <= System.currentTimeMillis()) && | ||||
|                         (jsonObject.get("endTime") == null || jsonObject.get("endTime", Date.class).getTime() >= System.currentTimeMillis()); | ||||
|                 return (jsonObject.get("getType") == null || jsonObject.get("getType", String.class).equals(CouponGetEnum.FREE.name())) && (jsonObject.get("startTime") != null && jsonObject.get("startTime", Date.class).getTime() <= System.currentTimeMillis()) && (jsonObject.get("endTime") == null || jsonObject.get("endTime", Date.class).getTime() >= System.currentTimeMillis()); | ||||
|             }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); | ||||
| 
 | ||||
|             Optional<Map.Entry<String, Object>> containsPromotion = promotionMap.entrySet().stream().filter(i -> | ||||
|                     i.getKey().contains(PromotionTypeEnum.SECKILL.name()) || i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst(); | ||||
|             Optional<Map.Entry<String, Object>> containsPromotion = promotionMap.entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.SECKILL.name()) || i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst(); | ||||
|             if (containsPromotion.isPresent()) { | ||||
|                 JSONObject jsonObject = JSONUtil.parseObj(containsPromotion.get().getValue()); | ||||
|                 PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams(); | ||||
| @ -305,6 +299,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i | ||||
| 
 | ||||
|         //获取分类 | ||||
|         String[] split = goodsSkuDetail.getCategoryPath().split(","); | ||||
|         map.put("wholesaleList", wholesaleService.findByGoodsId(goodsSkuDetail.getGoodsId())); | ||||
|         map.put("categoryName", categoryService.getCategoryNameByIds(Arrays.asList(split))); | ||||
| 
 | ||||
|         //获取规格信息 | ||||
| @ -347,7 +342,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i | ||||
|                 cache.put(GoodsSkuService.getCacheKeys(sku.getId()), sku); | ||||
|             } | ||||
|             if (!goodsSkus.isEmpty()) { | ||||
|                 generateEs(goods); | ||||
|                 this.generateEs(goods); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @ -565,10 +560,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i | ||||
| 
 | ||||
| 
 | ||||
|         //修改规格索引,发送mq消息 | ||||
|         Map<String, Object> updateIndexFieldsMap = EsIndexUtil.getUpdateIndexFieldsMap( | ||||
|                 MapUtil.builder(new HashMap<String, Object>()).put("id", goodsSku.getId()).build(), | ||||
|                 MapUtil.builder(new HashMap<String, Object>()).put("commentNum", goodsSku.getCommentNum()).put("highPraiseNum", highPraiseNum) | ||||
|                         .put("grade", grade).build()); | ||||
|         Map<String, Object> updateIndexFieldsMap = EsIndexUtil.getUpdateIndexFieldsMap(MapUtil.builder(new HashMap<String, Object>()).put("id", goodsSku.getId()).build(), MapUtil.builder(new HashMap<String, Object>()).put("commentNum", goodsSku.getCommentNum()).put("highPraiseNum", highPraiseNum).put("grade", grade).build()); | ||||
|         String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.UPDATE_GOODS_INDEX_FIELD.name(); | ||||
|         rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(updateIndexFieldsMap), RocketmqSendCallbackBuilder.commonCallback()); | ||||
| 
 | ||||
| @ -632,153 +624,25 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * 增加sku集合 | ||||
|      * 批量渲染商品sku | ||||
|      * | ||||
|      * @param skuList sku列表 | ||||
|      * @param goods   商品信息 | ||||
|      * @param goodsSkuList      sku集合 | ||||
|      * @param goodsOperationDTO 商品操作DTO | ||||
|      */ | ||||
|     List<GoodsSku> addGoodsSku(List<Map<String, Object>> skuList, Goods goods) { | ||||
|         List<GoodsSku> skus = new ArrayList<>(); | ||||
|         for (Map<String, Object> skuVO : skuList) { | ||||
|             Map<String, Object> resultMap = this.add(skuVO, goods); | ||||
|             GoodsSku goodsSku = (GoodsSku) resultMap.get("goodsSku"); | ||||
|             if (goods.getSelfOperated() != null) { | ||||
|                 goodsSku.setSelfOperated(goods.getSelfOperated()); | ||||
|             } | ||||
|             goodsSku.setGoodsType(goods.getGoodsType()); | ||||
|             skus.add(goodsSku); | ||||
|             cache.put(GoodsSkuService.getStockCacheKey(goodsSku.getId()), goodsSku.getQuantity()); | ||||
|         } | ||||
|         this.saveOrUpdateBatch(skus); | ||||
|         return skus; | ||||
|     void renderGoodsSkuList(List<GoodsSku> goodsSkuList, GoodsOperationDTO goodsOperationDTO) { | ||||
|         // 商品销售模式渲染器 | ||||
|         salesModelRenders.stream().filter(i -> i.getSalesMode().equals(goodsOperationDTO.getSalesModel())).findFirst().ifPresent(i -> i.renderBatch(goodsSkuList, goodsOperationDTO)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 添加商品规格 | ||||
|      * 渲染商品sku | ||||
|      * | ||||
|      * @param map   规格属性 | ||||
|      * @param goods 商品 | ||||
|      * @return 规格商品 | ||||
|      * @param goodsSku          sku | ||||
|      * @param goodsOperationDTO 商品操作DTO | ||||
|      */ | ||||
|     private Map<String, Object> add(Map<String, Object> map, Goods goods) { | ||||
|         Map<String, Object> resultMap = new HashMap<>(2); | ||||
|         GoodsSku sku = new GoodsSku(); | ||||
| 
 | ||||
|         //商品索引 | ||||
|         EsGoodsIndex esGoodsIndex = new EsGoodsIndex(); | ||||
| 
 | ||||
|         //设置商品信息 | ||||
|         goodsInfo(sku, goods); | ||||
|         //设置商品规格信息 | ||||
|         skuInfo(sku, goods, map, esGoodsIndex); | ||||
| 
 | ||||
|         esGoodsIndex.setGoodsSku(sku); | ||||
|         resultMap.put("goodsSku", sku); | ||||
|         resultMap.put("goodsIndex", esGoodsIndex); | ||||
|         return resultMap; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 设置规格商品的商品信息 | ||||
|      * | ||||
|      * @param sku   规格 | ||||
|      * @param goods 商品 | ||||
|      */ | ||||
|     private void goodsInfo(GoodsSku sku, Goods goods) { | ||||
|         //商品基本信息 | ||||
|         sku.setGoodsId(goods.getId()); | ||||
| 
 | ||||
|         sku.setSellingPoint(goods.getSellingPoint()); | ||||
|         sku.setCategoryPath(goods.getCategoryPath()); | ||||
|         sku.setBrandId(goods.getBrandId()); | ||||
|         sku.setMarketEnable(goods.getMarketEnable()); | ||||
|         sku.setIntro(goods.getIntro()); | ||||
|         sku.setMobileIntro(goods.getMobileIntro()); | ||||
|         sku.setGoodsUnit(goods.getGoodsUnit()); | ||||
|         sku.setGrade(100D); | ||||
|         //商品状态 | ||||
|         sku.setAuthFlag(goods.getAuthFlag()); | ||||
|         sku.setSalesModel(goods.getSalesModel()); | ||||
|         //卖家信息 | ||||
|         sku.setStoreId(goods.getStoreId()); | ||||
|         sku.setStoreName(goods.getStoreName()); | ||||
|         sku.setStoreCategoryPath(goods.getStoreCategoryPath()); | ||||
|         sku.setFreightTemplateId(goods.getTemplateId()); | ||||
|         sku.setRecommend(goods.getRecommend()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 设置商品规格信息 | ||||
|      * | ||||
|      * @param sku          规格商品 | ||||
|      * @param goods        商品 | ||||
|      * @param map          规格信息 | ||||
|      * @param esGoodsIndex 商品索引 | ||||
|      */ | ||||
|     private void skuInfo(GoodsSku sku, Goods goods, Map<String, Object> map, EsGoodsIndex esGoodsIndex) { | ||||
| 
 | ||||
|         //规格简短信息 | ||||
|         StringBuilder simpleSpecs = new StringBuilder(); | ||||
|         //商品名称 | ||||
|         StringBuilder goodsName = new StringBuilder(goods.getGoodsName()); | ||||
|         //规格商品缩略图 | ||||
|         String thumbnail = ""; | ||||
|         String small = ""; | ||||
|         //规格值 | ||||
|         Map<String, Object> specMap = new HashMap<>(16); | ||||
|         //商品属性 | ||||
|         List<EsGoodsAttribute> attributes = new ArrayList<>(); | ||||
| 
 | ||||
|         //获取规格信息 | ||||
|         for (Map.Entry<String, Object> spec : map.entrySet()) { | ||||
|             //保存规格信息 | ||||
|             if (("id").equals(spec.getKey()) || ("sn").equals(spec.getKey()) || ("cost").equals(spec.getKey()) | ||||
|                     || ("price").equals(spec.getKey()) || ("quantity").equals(spec.getKey()) | ||||
|                     || ("weight").equals(spec.getKey())) { | ||||
|                 continue; | ||||
|             } else { | ||||
|                 specMap.put(spec.getKey(), spec.getValue()); | ||||
|                 if (("images").equals(spec.getKey())) { | ||||
|                     //设置规格商品缩略图 | ||||
|                     List<Map<String, String>> images = (List<Map<String, String>>) spec.getValue(); | ||||
|                     if (images == null || images.isEmpty()) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     //设置规格商品缩略图 | ||||
|                     //如果规格没有图片,则用商品图片复盖。有则增加规格图片,放在商品图片集合之前 | ||||
|                     if (CharSequenceUtil.isNotEmpty(spec.getValue().toString())) { | ||||
|                         thumbnail = goodsGalleryService.getGoodsGallery(images.get(0).get("url")).getThumbnail(); | ||||
|                         small = goodsGalleryService.getGoodsGallery(images.get(0).get("url")).getSmall(); | ||||
|                     } | ||||
|                 } else { | ||||
|                     if (spec.getValue() != null) { | ||||
|                         //设置商品名称 | ||||
|                         goodsName.append(" ").append(spec.getValue()); | ||||
|                         //规格简短信息 | ||||
|                         simpleSpecs.append(" ").append(spec.getValue()); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         //设置规格信息 | ||||
|         sku.setGoodsName(goodsName.toString()); | ||||
|         sku.setThumbnail(thumbnail); | ||||
|         sku.setSmall(small); | ||||
| 
 | ||||
|         //规格信息 | ||||
|         sku.setId(Convert.toStr(map.get("id"), "")); | ||||
|         sku.setSn(Convert.toStr(map.get("sn"))); | ||||
|         sku.setWeight(Convert.toDouble(map.get("weight"), 0D)); | ||||
|         sku.setPrice(Convert.toDouble(map.get("price"), 0D)); | ||||
|         sku.setCost(Convert.toDouble(map.get("cost"), 0D)); | ||||
|         sku.setQuantity(Convert.toInt(map.get("quantity"), 0)); | ||||
|         sku.setSpecs(JSONUtil.toJsonStr(specMap)); | ||||
|         sku.setSimpleSpecs(simpleSpecs.toString()); | ||||
| 
 | ||||
|         if (esGoodsIndex != null) { | ||||
|             //商品索引 | ||||
|             esGoodsIndex.setAttrList(attributes); | ||||
|         } | ||||
|     void renderGoodsSku(GoodsSku goodsSku, GoodsOperationDTO goodsOperationDTO) { | ||||
|         // 商品销售模式渲染器 | ||||
|         salesModelRenders.stream().filter(i -> i.getSalesMode().equals(goodsOperationDTO.getSalesModel())).findFirst().ifPresent(i -> i.renderSingle(goodsSku, goodsOperationDTO)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -0,0 +1,64 @@ | ||||
| package cn.lili.modules.goods.serviceimpl; | ||||
| 
 | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.lili.cache.Cache; | ||||
| import cn.lili.modules.goods.entity.dos.Wholesale; | ||||
| import cn.lili.modules.goods.mapper.WholesaleMapper; | ||||
| import cn.lili.modules.goods.service.WholesaleService; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.cache.annotation.CacheConfig; | ||||
| import org.springframework.cache.annotation.CacheEvict; | ||||
| import org.springframework.cache.annotation.Cacheable; | ||||
| import org.springframework.stereotype.Service; | ||||
| 
 | ||||
| import java.util.Comparator; | ||||
| import java.util.List; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| /** | ||||
|  * @author paulG | ||||
|  * @since 2022/5/24 | ||||
|  **/ | ||||
| @Service | ||||
| @CacheConfig(cacheNames = "{wholesale}_") | ||||
| public class WholesaleServiceImpl extends ServiceImpl<WholesaleMapper, Wholesale> implements WholesaleService { | ||||
| 
 | ||||
|     @Autowired | ||||
|     private Cache<List<Wholesale>> cache; | ||||
| 
 | ||||
|     @Override | ||||
|     @Cacheable(key = "#goodsId") | ||||
|     public List<Wholesale> findByGoodsId(String goodsId) { | ||||
|         LambdaQueryWrapper<Wholesale> queryWrapper = new LambdaQueryWrapper<>(); | ||||
|         queryWrapper.eq(Wholesale::getGoodsId, goodsId); | ||||
|         return this.list(queryWrapper).stream().sorted(Comparator.comparing(Wholesale::getNum)).collect(Collectors.toList()); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     @CacheEvict(key = "#goodsId") | ||||
|     public Boolean removeByGoodsId(String goodsId) { | ||||
|         LambdaQueryWrapper<Wholesale> queryWrapper = new LambdaQueryWrapper<>(); | ||||
|         queryWrapper.eq(Wholesale::getGoodsId, goodsId); | ||||
|         return this.remove(queryWrapper); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Wholesale match(String goodsId, Integer num) { | ||||
|         List<Wholesale> wholesaleList = cache.get("{wholesale}_" + goodsId); | ||||
|         if (wholesaleList == null) { | ||||
|             wholesaleList = this.findByGoodsId(goodsId); | ||||
|             cache.put("{wholesale}_" + goodsId, wholesaleList); | ||||
|         } | ||||
|         List<Wholesale> matchList = wholesaleList.stream() | ||||
|                 .filter(wholesale -> wholesale.getNum() <= num) | ||||
|                 .collect(Collectors.toList()); | ||||
|         if (CollUtil.isNotEmpty(matchList)) { | ||||
|             return matchList.get(matchList.size() - 1); | ||||
|         } else if (CollUtil.isNotEmpty(wholesaleList) && CollUtil.isEmpty(matchList)) { | ||||
|             return wholesaleList.get(0); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,114 @@ | ||||
| package cn.lili.modules.goods.sku; | ||||
| 
 | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.convert.Convert; | ||||
| import cn.hutool.core.lang.Assert; | ||||
| import cn.hutool.json.JSONUtil; | ||||
| import cn.lili.modules.goods.entity.dos.Goods; | ||||
| import cn.lili.modules.goods.entity.dos.GoodsSku; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsOperationDTO; | ||||
| import org.springframework.stereotype.Component; | ||||
| 
 | ||||
| import java.util.*; | ||||
| 
 | ||||
| /** | ||||
|  * @author paulG | ||||
|  * @since 2022/5/20 | ||||
|  **/ | ||||
| @Component | ||||
| public class GoodsSkuBuilder { | ||||
| 
 | ||||
| 
 | ||||
|     private static final String IMAGES_KEY = "images"; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * 构建商品sku | ||||
|      * | ||||
|      * @param goods             商品 | ||||
|      * @param skuInfo           sku信息列表 | ||||
|      * @param goodsOperationDTO 商品操作信息(如需处理额外信息传递,不需可传空) | ||||
|      * @return 商品sku | ||||
|      */ | ||||
|     public static GoodsSku build(Goods goods, Map<String, Object> skuInfo, GoodsOperationDTO goodsOperationDTO) { | ||||
|         GoodsSku goodsSku = new GoodsSku(goods); | ||||
|         builderSingle(goodsSku, skuInfo, goodsOperationDTO); | ||||
|         return goodsSku; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 批量构建商品sku | ||||
|      * | ||||
|      * @param goods             商品 | ||||
|      * @param goodsOperationDTO 商品操作信息 | ||||
|      * @return 商品sku | ||||
|      */ | ||||
|     public static List<GoodsSku> buildBatch(Goods goods, GoodsOperationDTO goodsOperationDTO) { | ||||
|         return builderBatch(goods, goodsOperationDTO); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 从已有的商品sku中构建商品sku | ||||
|      * | ||||
|      * @param goodsSku          原商品sku | ||||
|      * @param skuInfo           sku信息列表 | ||||
|      * @param goodsOperationDTO 商品操作信息(如需处理额外信息传递,不需可传空) | ||||
|      * @return 商品sku | ||||
|      */ | ||||
|     public static GoodsSku build(GoodsSku goodsSku, Map<String, Object> skuInfo, GoodsOperationDTO goodsOperationDTO) { | ||||
|         builderSingle(goodsSku, skuInfo, goodsOperationDTO); | ||||
|         return goodsSku; | ||||
|     } | ||||
| 
 | ||||
|     private static void builderSingle(GoodsSku goodsSku, Map<String, Object> skuInfo, GoodsOperationDTO goodsOperationDTO) { | ||||
|         Assert.notNull(goodsSku, "goodsSku不能为空"); | ||||
|         Assert.notEmpty(skuInfo, "skuInfo不能为空"); | ||||
|         //规格简短信息 | ||||
|         StringBuilder simpleSpecs = new StringBuilder(); | ||||
|         //商品名称 | ||||
|         StringBuilder goodsName = new StringBuilder(goodsOperationDTO.getGoodsName()); | ||||
|         //规格值 | ||||
|         Map<String, Object> specMap = new HashMap<>(16); | ||||
| 
 | ||||
|         // 原始规格项 | ||||
|         String[] ignoreOriginKeys = {"id", "sn", "cost", "price", "quantity", "weight", IMAGES_KEY}; | ||||
|         //获取规格信息 | ||||
|         for (Map.Entry<String, Object> spec : skuInfo.entrySet()) { | ||||
|             //保存新增规格信息 | ||||
|             if (!CollUtil.contains(Arrays.asList(ignoreOriginKeys), spec.getKey()) && spec.getValue() != null) { | ||||
|                 specMap.put(spec.getKey(), spec.getValue()); | ||||
|                 //设置商品名称 | ||||
|                 goodsName.append(" ").append(spec.getValue()); | ||||
|                 //规格简短信息 | ||||
|                 simpleSpecs.append(" ").append(spec.getValue()); | ||||
|             } | ||||
|         } | ||||
|         //设置规格信息 | ||||
|         goodsSku.setGoodsName(goodsName.toString()); | ||||
| 
 | ||||
| 
 | ||||
|         //规格信息 | ||||
|         goodsSku.setId(Convert.toStr(skuInfo.get("id"), "")); | ||||
|         goodsSku.setSn(Convert.toStr(skuInfo.get("sn"))); | ||||
|         goodsSku.setWeight(Convert.toDouble(skuInfo.get("weight"), 0D)); | ||||
|         goodsSku.setPrice(Convert.toDouble(skuInfo.get("price"), 0D)); | ||||
|         goodsSku.setCost(Convert.toDouble(skuInfo.get("cost"), 0D)); | ||||
|         goodsSku.setQuantity(Convert.toInt(skuInfo.get("quantity"), 0)); | ||||
|         goodsSku.setSpecs(JSONUtil.toJsonStr(specMap)); | ||||
|         goodsSku.setSimpleSpecs(simpleSpecs.toString()); | ||||
|     } | ||||
| 
 | ||||
|     private static List<GoodsSku> builderBatch(Goods goods, GoodsOperationDTO goodsOperationDTO) { | ||||
|         Assert.notEmpty(goodsOperationDTO.getSkuList(), "goodsOperationDTO.getSkuList()不能为空"); | ||||
|         Assert.notNull(goods, "goods不能为空"); | ||||
|         List<GoodsSku> goodsSkus = new ArrayList<>(); | ||||
|         for (Map<String, Object> skuInfo : goodsOperationDTO.getSkuList()) { | ||||
|             GoodsSku goodsSku = new GoodsSku(goods); | ||||
|             builderSingle(goodsSku, skuInfo, goodsOperationDTO); | ||||
|             goodsSkus.add(goodsSku); | ||||
|         } | ||||
|         return goodsSkus; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,23 @@ | ||||
| package cn.lili.modules.goods.sku.render; | ||||
| 
 | ||||
| import cn.lili.modules.goods.entity.dos.GoodsSku; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsOperationDTO; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * 根据商品销售模型渲染商品sku | ||||
|  * | ||||
|  * @author paulG | ||||
|  * @since 2022/5/20 | ||||
|  **/ | ||||
| public interface SalesModelRender { | ||||
| 
 | ||||
| 
 | ||||
|     String getSalesMode(); | ||||
| 
 | ||||
|     void renderSingle(GoodsSku goodsSku, GoodsOperationDTO goodsOperationDTO); | ||||
| 
 | ||||
|     void renderBatch(List<GoodsSku> goodsSkus, GoodsOperationDTO goodsOperationDTO); | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,76 @@ | ||||
| package cn.lili.modules.goods.sku.render.impl; | ||||
| 
 | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.lang.Assert; | ||||
| import cn.lili.common.enums.ResultCode; | ||||
| import cn.lili.common.exception.ServiceException; | ||||
| import cn.lili.modules.goods.entity.dos.GoodsSku; | ||||
| import cn.lili.modules.goods.entity.dos.Wholesale; | ||||
| import cn.lili.modules.goods.entity.dto.GoodsOperationDTO; | ||||
| import cn.lili.modules.goods.entity.dto.WholesaleDTO; | ||||
| import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum; | ||||
| import cn.lili.modules.goods.service.WholesaleService; | ||||
| import cn.lili.modules.goods.sku.render.SalesModelRender; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Component; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
| 
 | ||||
| import java.util.Comparator; | ||||
| import java.util.List; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| /** | ||||
|  * @author paulG | ||||
|  * @since 2022/5/24 | ||||
|  **/ | ||||
| @Component | ||||
| public class WholesaleSaleModelRenderImpl implements SalesModelRender { | ||||
|     /** | ||||
|      * 批发商品 | ||||
|      */ | ||||
|     @Autowired | ||||
|     private WholesaleService wholesaleService; | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void renderSingle(GoodsSku goodsSku, GoodsOperationDTO goodsOperationDTO) { | ||||
|         Assert.notEmpty(goodsOperationDTO.getWholesaleList(), "批发规则不能为空"); | ||||
|         this.checkWholesaleList(goodsOperationDTO.getWholesaleList()); | ||||
|         List<Wholesale> collect = goodsOperationDTO.getWholesaleList().stream().sorted(Comparator.comparing(Wholesale::getPrice)).collect(Collectors.toList()); | ||||
|         wholesaleService.removeByGoodsId(goodsOperationDTO.getGoodsId()); | ||||
|         wholesaleService.saveOrUpdateBatch(collect); | ||||
|         goodsSku.setPrice(collect.get(0).getPrice()); | ||||
|         goodsSku.setCost(collect.get(0).getPrice()); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void renderBatch(List<GoodsSku> goodsSkus, GoodsOperationDTO goodsOperationDTO) { | ||||
|         Assert.notEmpty(goodsOperationDTO.getWholesaleList(), "批发规则不能为空"); | ||||
|         this.checkWholesaleList(goodsOperationDTO.getWholesaleList()); | ||||
|         List<Wholesale> collect = goodsOperationDTO.getWholesaleList().stream().sorted(Comparator.comparing(Wholesale::getPrice)).collect(Collectors.toList()); | ||||
|         for (GoodsSku skus : goodsSkus) { | ||||
|             skus.setPrice(collect.get(0).getPrice()); | ||||
|             skus.setCost(collect.get(0).getPrice()); | ||||
|         } | ||||
|         wholesaleService.removeByGoodsId(goodsOperationDTO.getGoodsId()); | ||||
|         wholesaleService.saveOrUpdateBatch(collect); | ||||
|     } | ||||
| 
 | ||||
|     private void checkWholesaleList(List<WholesaleDTO> wholesaleList) { | ||||
|         if (CollUtil.isEmpty(wholesaleList)) { | ||||
|             throw new ServiceException(ResultCode.MUST_HAVE_SALES_MODEL); | ||||
|         } | ||||
|         for (WholesaleDTO wholesaleDTO : wholesaleList) { | ||||
|             if (wholesaleDTO.getPrice() == null || wholesaleDTO.getPrice() <= 0 || wholesaleDTO.getNum() == null || wholesaleDTO.getNum() <= 0) { | ||||
|                 throw new ServiceException(ResultCode.HAVE_INVALID_SALES_MODEL); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public String getSalesMode() { | ||||
|         return GoodsSalesModeEnum.WHOLESALE.name(); | ||||
|     } | ||||
| } | ||||
| @ -1,5 +1,6 @@ | ||||
| package cn.lili.modules.order.cart.render.impl; | ||||
| 
 | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.text.CharSequenceUtil; | ||||
| import cn.hutool.json.JSONObject; | ||||
| import cn.hutool.json.JSONUtil; | ||||
| @ -7,10 +8,14 @@ import cn.lili.common.enums.PromotionTypeEnum; | ||||
| import cn.lili.common.enums.ResultCode; | ||||
| import cn.lili.common.exception.ServiceException; | ||||
| import cn.lili.common.security.context.UserContext; | ||||
| import cn.lili.common.utils.CurrencyUtil; | ||||
| import cn.lili.modules.goods.entity.dos.GoodsSku; | ||||
| import cn.lili.modules.goods.entity.dos.Wholesale; | ||||
| import cn.lili.modules.goods.entity.enums.GoodsAuthEnum; | ||||
| import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum; | ||||
| import cn.lili.modules.goods.entity.enums.GoodsStatusEnum; | ||||
| import cn.lili.modules.goods.service.GoodsSkuService; | ||||
| import cn.lili.modules.goods.service.WholesaleService; | ||||
| import cn.lili.modules.member.entity.dos.Member; | ||||
| import cn.lili.modules.member.service.MemberService; | ||||
| import cn.lili.modules.order.cart.entity.dto.TradeDTO; | ||||
| @ -55,6 +60,9 @@ public class CheckDataRender implements CartRenderStep { | ||||
|     @Autowired | ||||
|     private MemberService memberService; | ||||
| 
 | ||||
|     @Autowired | ||||
|     private WholesaleService wholesaleService; | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public RenderStepEnums step() { | ||||
| @ -69,6 +77,7 @@ public class CheckDataRender implements CartRenderStep { | ||||
|         //校验商品有效性 | ||||
|         checkData(tradeDTO); | ||||
| 
 | ||||
|         preSaleModel(tradeDTO); | ||||
|         //店铺分组数据初始化 | ||||
|         groupStore(tradeDTO); | ||||
| 
 | ||||
| @ -212,4 +221,29 @@ public class CheckDataRender implements CartRenderStep { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * 商品销售模式特殊处理 | ||||
|      * | ||||
|      * @param tradeDTO 交易信息 | ||||
|      */ | ||||
|     private void preSaleModel(TradeDTO tradeDTO) { | ||||
|         // 寻找同goods下销售模式为批发的商品 | ||||
|         Map<String, List<CartSkuVO>> goodsGroup = tradeDTO.getSkuList().stream().filter(i -> i.getGoodsSku().getSalesModel().equals(GoodsSalesModeEnum.WHOLESALE.name())).collect(Collectors.groupingBy(i -> i.getGoodsSku().getGoodsId())); | ||||
|         if (CollUtil.isNotEmpty(goodsGroup)) { | ||||
|             goodsGroup.forEach((k, v) -> { | ||||
|                 // 获取购买总数 | ||||
|                 int sum = v.stream().mapToInt(CartSkuVO::getNum).sum(); | ||||
|                 // 匹配符合的批发规则 | ||||
|                 Wholesale match = wholesaleService.match(k, sum); | ||||
|                 if (match != null) { | ||||
|                     v.forEach(i -> { | ||||
|                         // 将符合规则的商品设置批发价格 | ||||
|                         i.setPurchasePrice(match.getPrice()); | ||||
|                         i.setSubTotal(CurrencyUtil.mul(i.getPurchasePrice(), i.getNum())); | ||||
|                     }); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| package cn.lili.modules.order.cart.service; | ||||
| 
 | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.text.CharSequenceUtil; | ||||
| import cn.hutool.json.JSONObject; | ||||
| import cn.hutool.json.JSONUtil; | ||||
| @ -11,11 +12,14 @@ import cn.lili.common.security.AuthUser; | ||||
| import cn.lili.common.security.context.UserContext; | ||||
| import cn.lili.common.utils.CurrencyUtil; | ||||
| import cn.lili.modules.goods.entity.dos.GoodsSku; | ||||
| import cn.lili.modules.goods.entity.dos.Wholesale; | ||||
| import cn.lili.modules.goods.entity.enums.GoodsAuthEnum; | ||||
| import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum; | ||||
| import cn.lili.modules.goods.entity.enums.GoodsStatusEnum; | ||||
| import cn.lili.modules.goods.entity.vos.GoodsVO; | ||||
| import cn.lili.modules.goods.service.GoodsService; | ||||
| import cn.lili.modules.goods.service.GoodsSkuService; | ||||
| import cn.lili.modules.goods.service.WholesaleService; | ||||
| import cn.lili.modules.member.entity.dos.Member; | ||||
| import cn.lili.modules.member.entity.dos.MemberAddress; | ||||
| import cn.lili.modules.member.service.MemberAddressService; | ||||
| @ -124,6 +128,9 @@ public class CartServiceImpl implements CartService { | ||||
|     @Autowired | ||||
|     private PromotionGoodsService promotionGoodsService; | ||||
| 
 | ||||
|     @Autowired | ||||
|     private WholesaleService wholesaleService; | ||||
| 
 | ||||
|     @Override | ||||
|     public void add(String skuId, Integer num, String cartType, Boolean cover) { | ||||
|         AuthUser currentUser = Objects.requireNonNull(UserContext.getCurrentUser()); | ||||
| @ -193,6 +200,7 @@ public class CartServiceImpl implements CartService { | ||||
|                 cartSkuVOS.add(cartSkuVO); | ||||
|             } | ||||
| 
 | ||||
|             this.checkGoodsSaleModel(dataSku, tradeDTO.getSkuList()); | ||||
|             tradeDTO.setCartTypeEnum(cartTypeEnum); | ||||
|             //如购物车发生更改,则重置优惠券 | ||||
|             tradeDTO.setStoreCoupons(null); | ||||
| @ -554,12 +562,9 @@ public class CartServiceImpl implements CartService { | ||||
|             goodsIndex = goodsIndexService.getResetEsGoodsIndex(dataSku, goodsVO.getGoodsParamsDTOList()); | ||||
|         } | ||||
|         if (goodsIndex.getPromotionMap() != null && !goodsIndex.getPromotionMap().isEmpty()) { | ||||
|             if (goodsIndex.getPromotionMap().keySet().stream().anyMatch(i -> i.contains(PromotionTypeEnum.SECKILL.name())) || | ||||
|                     (goodsIndex.getPromotionMap().keySet().stream().anyMatch(i -> i.contains(PromotionTypeEnum.PINTUAN.name())) | ||||
|                             && CartTypeEnum.PINTUAN.name().equals(cartType))) { | ||||
|             if (goodsIndex.getPromotionMap().keySet().stream().anyMatch(i -> i.contains(PromotionTypeEnum.SECKILL.name())) || (goodsIndex.getPromotionMap().keySet().stream().anyMatch(i -> i.contains(PromotionTypeEnum.PINTUAN.name())) && CartTypeEnum.PINTUAN.name().equals(cartType))) { | ||||
| 
 | ||||
|                 Optional<Map.Entry<String, Object>> containsPromotion = goodsIndex.getPromotionMap().entrySet().stream().filter(i -> | ||||
|                         i.getKey().contains(PromotionTypeEnum.SECKILL.name()) || i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst(); | ||||
|                 Optional<Map.Entry<String, Object>> containsPromotion = goodsIndex.getPromotionMap().entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.SECKILL.name()) || i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst(); | ||||
|                 if (containsPromotion.isPresent()) { | ||||
|                     JSONObject promotionsObj = JSONUtil.parseObj(containsPromotion.get().getValue()); | ||||
|                     PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams(); | ||||
| @ -709,6 +714,24 @@ public class CartServiceImpl implements CartService { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     private void checkGoodsSaleModel(GoodsSku dataSku, List<CartSkuVO> cartSkuVOS) { | ||||
|         if (dataSku.getSalesModel().equals(GoodsSalesModeEnum.WHOLESALE.name())) { | ||||
|             int numSum = 0; | ||||
|             List<CartSkuVO> sameGoodsIdSkuList = cartSkuVOS.stream().filter(i -> i.getGoodsSku().getGoodsId().equals(dataSku.getGoodsId())).collect(Collectors.toList()); | ||||
|             if (CollUtil.isNotEmpty(sameGoodsIdSkuList)) { | ||||
|                 numSum += sameGoodsIdSkuList.stream().mapToInt(CartSkuVO::getNum).sum(); | ||||
|             } | ||||
|             Wholesale match = wholesaleService.match(dataSku.getGoodsId(), numSum); | ||||
|             if (match != null) { | ||||
|                 sameGoodsIdSkuList.forEach(i -> { | ||||
|                     i.setPurchasePrice(match.getPrice()); | ||||
|                     i.setSubTotal(CurrencyUtil.mul(i.getPurchasePrice(), i.getNum())); | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 校验拼团信息 | ||||
|      * | ||||
|  | ||||
| @ -5,8 +5,9 @@ import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import io.swagger.annotations.ApiModel; | ||||
| import io.swagger.annotations.ApiModelProperty; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| 
 | ||||
| import java.math.BigDecimal; | ||||
| import javax.validation.constraints.NotNull; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
| @ -18,11 +19,13 @@ import java.math.BigDecimal; | ||||
| @Data | ||||
| @TableName("li_department") | ||||
| @ApiModel(value = "部门") | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| public class Department extends BaseEntity { | ||||
| 
 | ||||
|     private static final long serialVersionUID = 1L; | ||||
| 
 | ||||
|     @ApiModelProperty(value = "部门名称") | ||||
|     @NotNull(message = "部门名称不能为空") | ||||
|     private String title; | ||||
| 
 | ||||
|     @ApiModelProperty(value = "父id") | ||||
|  | ||||
| @ -5,6 +5,8 @@ import lombok.AllArgsConstructor; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| 
 | ||||
| /** | ||||
|  * 促销skuVO | ||||
|  * | ||||
| @ -15,7 +17,9 @@ import lombok.NoArgsConstructor; | ||||
| @Data | ||||
| @AllArgsConstructor | ||||
| @NoArgsConstructor | ||||
| public class PromotionSkuVO { | ||||
| public class PromotionSkuVO implements Serializable { | ||||
| 
 | ||||
|     private static final long serialVersionUID = -8587010496940375179L; | ||||
| 
 | ||||
|     /** | ||||
|      * 促销类型 | ||||
|  | ||||
| @ -215,6 +215,7 @@ public class EsGoodsIndex implements Serializable { | ||||
| 
 | ||||
|     /** | ||||
|      * 销售模式 | ||||
|      * @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum | ||||
|      */ | ||||
|     @Field(type = FieldType.Text) | ||||
|     @ApiModelProperty("销售模式") | ||||
|  | ||||
| @ -1,15 +1,16 @@ | ||||
| package cn.lili.controller.permission; | ||||
| 
 | ||||
| import cn.lili.common.enums.ResultUtil; | ||||
| import cn.lili.mybatis.util.PageUtil; | ||||
| import cn.lili.common.vo.ResultMessage; | ||||
| import cn.lili.common.vo.SearchVO; | ||||
| import cn.lili.modules.permission.entity.dos.Department; | ||||
| import cn.lili.modules.permission.entity.vo.DepartmentVO; | ||||
| import cn.lili.modules.permission.service.DepartmentService; | ||||
| import cn.lili.mybatis.util.PageUtil; | ||||
| import io.swagger.annotations.Api; | ||||
| import io.swagger.annotations.ApiOperation; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| 
 | ||||
| import java.util.List; | ||||
| @ -45,15 +46,14 @@ public class DepartmentManagerController { | ||||
| 
 | ||||
|     @PostMapping | ||||
|     @ApiOperation(value = "新增部门") | ||||
|     public ResultMessage<Department> save(Department department) { | ||||
|     public ResultMessage<Department> save(@Validated Department department) { | ||||
|         departmentService.save(department); | ||||
|         return ResultUtil.data(department); | ||||
|     } | ||||
| 
 | ||||
|     @PutMapping("/{id}") | ||||
|     @ApiOperation(value = "更新部门") | ||||
|     public ResultMessage<Department> update(@PathVariable String id, Department department) { | ||||
|         departmentService.updateById(department); | ||||
|     public ResultMessage<Department> update(@PathVariable String id, @Validated Department department) { | ||||
|         departmentService.updateById(department); | ||||
|         return ResultUtil.data(department); | ||||
|     } | ||||
|  | ||||
							
								
								
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							| @ -26,11 +26,11 @@ | ||||
|         <images-version>1</images-version> | ||||
|         <alipay-sdk-version>4.22.32.ALL</alipay-sdk-version> | ||||
|         <mybatis-plus-version>3.5.1</mybatis-plus-version> | ||||
|         <Hutool-version>5.7.20</Hutool-version> | ||||
|         <Hutool-version>5.8.0</Hutool-version> | ||||
|         <TinyPinyin-verions>2.0.3.RELEASE</TinyPinyin-verions> | ||||
|         <jasypt-version>3.0.4</jasypt-version> | ||||
|         <neetl-version>2.9.10</neetl-version> | ||||
|         <lombok-version>1.18.22</lombok-version> | ||||
|         <lombok-version>1.18.24</lombok-version> | ||||
|         <redisson>3.15.6</redisson> | ||||
|         <aliyun-version>4.5.18</aliyun-version> | ||||
|         <aliyun-sdk-oss-version>3.11.1</aliyun-sdk-oss-version> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 OceansDeep
						OceansDeep