merge origin master

This commit is contained in:
paulGao
2021-11-03 15:29:48 +08:00
38 changed files with 348 additions and 298 deletions

View File

@@ -89,7 +89,7 @@ public interface Cache<T> {
*
* @param key 缓存key
*/
void remove(Object key);
Boolean remove(Object key);
/**
* 删除

View File

@@ -78,9 +78,9 @@ public class RedisCache implements Cache {
}
@Override
public void remove(Object key) {
public Boolean remove(Object key) {
redisTemplate.delete(key);
return redisTemplate.delete(key);
}
/**

View File

@@ -99,7 +99,8 @@ public enum ResultCode {
BRAND_DISABLE_ERROR(14003, "品牌禁用失败"),
BRAND_DELETE_ERROR(14004, "品牌删除失败"),
BRAND_NAME_EXIST_ERROR(20002, "品牌名称重复!"),
BRAND_USE_DISABLE_ERROR(20003, "分类已经绑定品牌,请先解除关联"),
BRAND_USE_DISABLE_ERROR(20003, "分类已经绑定品牌,请先解除关联"),
BRAND_BIND_GOODS_ERROR(20005, "品牌已经绑定商品,请先解除关联"),
BRAND_NOT_EXIST(20004, "品牌不存在"),
/**
@@ -154,7 +155,7 @@ public enum ResultCode {
* 购物车
*/
CART_ERROR(30001, "读取结算页的购物车异常"),
CART_PINTUAN_NOT_EXIST_ERROR(30002, "拼团活动不存在错误"),
CART_PINTUAN_NOT_EXIST_ERROR(30002, "拼团活动已关闭,请稍后重试"),
CART_PINTUAN_LIMIT_ERROR(30003, "购买数量超过拼团活动限制数量"),
SHIPPING_NOT_APPLY(30005, "购物商品不支持当前收货地址配送"),
@@ -240,7 +241,7 @@ public enum ResultCode {
* 活动
*/
PROMOTION_GOODS_NOT_EXIT(40000, "当前促销商品不存在!"),
PROMOTION_SAME_ACTIVE_EXIST(40001, "当前时间内已存在同类活动"),
PROMOTION_SAME_ACTIVE_EXIST(40001, "活动时间内已存在同类活动,请选择关闭、删除当前时段的活动"),
PROMOTION_START_TIME_ERROR(40002, "活动起始时间不能小于当前时间"),
PROMOTION_END_TIME_ERROR(40003, "活动结束时间不能小于当前时间"),
PROMOTION_TIME_ERROR(40004, "活动起始时间必须大于结束时间"),
@@ -425,8 +426,8 @@ public enum ResultCode {
*/
VERIFICATION_SEND_SUCCESS(80201, "短信验证码,发送成功"),
VERIFICATION_ERROR(80202, "验证失败"),
VERIFICATION_SMS_ERROR(80203, "短信验证码错误,请重新校验"),
VERIFICATION_SMS_EXPIRED_ERROR(80204, "验证码已失效,请重新校验"),
VERIFICATION_CODE_INVALID(80204, "验证码已失效,请重新校验"),
VERIFICATION_SMS_CHECKED_ERROR(80210, "短信验证码错误,请重新校验"),
/**
* 微信相关异常
@@ -449,9 +450,8 @@ public enum ResultCode {
CUSTOM_WORDS_SECRET_KEY_ERROR(90002, "秘钥验证失败!"),
CONNECT_NOT_EXIST(90000, "登录方式不存在!"),
ELASTICSEARCH_INDEX_INIT_ERROR(90003, "索引初始化失败!"),
PURCHASE_ORDER_DEADLINE_ERROR(90004,"供求单,已超过报名截止时间")
;
PURCHASE_ORDER_DEADLINE_ERROR(90004, "供求单,已超过报名截止时间"),
INDEX_BUILDING(90005, "索引正在生成");
private final Integer code;
private final String message;

View File

@@ -2,16 +2,20 @@ package cn.lili.common.exception;
import cn.lili.common.enums.ResultCode;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 全局业务异常类
*
* @author Chopper
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class ServiceException extends RuntimeException {
public static String DEFAULT_MESSAGE = "网络错误,请稍后重试!";
private static final long serialVersionUID = 3447728300174142127L;
public static final String DEFAULT_MESSAGE = "网络错误,请稍后重试!";
/**
* 异常消息

View File

@@ -24,7 +24,10 @@ public class ThreadPoolUtil {
*/
private static final BlockingQueue<Runnable> BQUEUE = new ArrayBlockingQueue<Runnable>(100);
private static final ThreadPoolExecutor POOL = new ThreadPoolExecutor(SIZE_CORE_POOL, SIZE_MAX_POOL, ALIVE_TIME, TimeUnit.MILLISECONDS, BQUEUE, new ThreadPoolExecutor.CallerRunsPolicy());
public static ThreadPoolExecutor threadPool;
/**
* volatile禁止指令重排
*/
public static volatile ThreadPoolExecutor threadPool;
static {
POOL.prestartAllCoreThreads();
@@ -49,22 +52,20 @@ public class ThreadPoolUtil {
}
/**
* dcs获取线程池
* DCL获取线程池
*
* @return 线程池对象
*/
public static ThreadPoolExecutor getThreadPool() {
if (threadPool != null) {
return threadPool;
} else {
synchronized (ThreadPoolUtil.class) {
if (threadPool == null) {
threadPool = (ThreadPoolExecutor) Executors.newCachedThreadPool();
return threadPool;
}
return threadPool;
}
synchronized (ThreadPoolUtil.class) {
if (threadPool == null) {
threadPool = (ThreadPoolExecutor) Executors.newCachedThreadPool();
}
}
return threadPool;
}
public static ThreadPoolExecutor getPool() {

View File

@@ -7,7 +7,6 @@ import cn.hutool.json.JSONUtil;
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.GoodsStatusEnum;
import cn.lili.mybatis.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -41,7 +40,7 @@ public class Goods extends BaseEntity {
@ApiModelProperty(value = "商品名称")
@NotEmpty(message = "商品名称不能为空")
@Length(max = 100, message = "商品名称提案仓不能超过100个字符")
@Length(max = 100, message = "商品名称太长不能超过100个字符")
private String goodsName;
@ApiModelProperty(value = "商品价格", required = true)

View File

@@ -35,7 +35,7 @@ public interface CategoryBrandService extends IService<CategoryBrand> {
* @param brandId 品牌ID
* @return 分类品牌关联信息
*/
List<CategoryBrand> getCategoryBrandListByBrandId(String brandId);
List<CategoryBrand> getCategoryBrandListByBrandId(List<String> brandId);
/**
* 保存分类品牌关系

View File

@@ -20,6 +20,13 @@ import java.util.List;
public interface GoodsService extends IService<Goods> {
/**
* 根据品牌获取商品
*
* @param brandIds 品牌ids
*/
List<Goods> getByBrandIds(List<String> brandIds);
/**
* 下架所有商家商品
*

View File

@@ -143,6 +143,13 @@ public interface GoodsSkuService extends IService<GoodsSku> {
*/
void updateGoodsSkuStatus(Goods goods);
/**
* 发送生成ES商品索引
*
* @param goods 商品信息
*/
void generateEs(Goods goods);
/**
* 更新SKU库存
*

View File

@@ -5,12 +5,14 @@ import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.goods.entity.dos.Brand;
import cn.lili.modules.goods.entity.dos.CategoryBrand;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dto.BrandPageDTO;
import cn.lili.modules.goods.entity.vos.BrandVO;
import cn.lili.modules.goods.mapper.BrandMapper;
import cn.lili.modules.goods.service.BrandService;
import cn.lili.modules.goods.service.CategoryBrandService;
import cn.lili.modules.goods.service.CategoryService;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -44,6 +46,9 @@ public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand> implements
@Autowired
private CategoryService categoryService;
@Autowired
private GoodsService goodsService;
@Override
public IPage<Brand> getBrandsByPage(BrandPageDTO page) {
LambdaQueryWrapper<Brand> queryWrapper = new LambdaQueryWrapper<>();
@@ -88,7 +93,9 @@ public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand> implements
Brand brand = this.checkExist(brandId);
//如果是要禁用,则需要先判定绑定关系
if (Boolean.TRUE.equals(disable)) {
checkoutCategory(brandId);
List<String> ids = new ArrayList<>();
ids.add(brandId);
checkBind(ids);
}
brand.setDeleteFlag(disable);
return updateById(brand);
@@ -96,7 +103,7 @@ public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand> implements
@Override
public void deleteBrands(List<String> ids) {
ids.forEach(this::checkoutCategory);
checkBind(ids);
this.removeByIds(ids);
}
@@ -104,16 +111,32 @@ public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand> implements
/**
* 校验绑定关系
*
* @param brandId
* @param brandIds
*/
private void checkoutCategory(String brandId) {
private void checkBind(List<String> brandIds) {
//分了绑定关系查询
List<CategoryBrand> categoryBrands = categoryBrandService.getCategoryBrandListByBrandId(brandId);
List<CategoryBrand> categoryBrands = categoryBrandService.getCategoryBrandListByBrandId(brandIds);
if (!categoryBrands.isEmpty()) {
List<String> brandIds = categoryBrands.stream().map(CategoryBrand::getCategoryId).collect(Collectors.toList());
List<String> categoryIds = categoryBrands.stream().map(CategoryBrand::getCategoryId).collect(Collectors.toList());
throw new ServiceException(ResultCode.BRAND_USE_DISABLE_ERROR,
JSONUtil.toJsonStr(categoryService.getCategoryNameByIds(brandIds)));
JSONUtil.toJsonStr(categoryService.getCategoryNameByIds(categoryIds)));
}
//分了商品绑定关系查询
List<Goods> goods = goodsService.getByBrandIds(brandIds);
if (!goods.isEmpty()) {
List<String> goodsNames = goods.stream().map(Goods::getGoodsName).collect(Collectors.toList());
throw new ServiceException(ResultCode.BRAND_BIND_GOODS_ERROR,
JSONUtil.toJsonStr(goodsNames));
}
}
/**
* 校验绑定关系
*
* @param brandIds
*/
private void checkoutGoods(List<String> brandIds) {
}
/**

View File

@@ -7,8 +7,6 @@ import cn.lili.modules.goods.service.CategoryBrandService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -36,8 +34,8 @@ public class CategoryBrandServiceImpl extends ServiceImpl<CategoryBrandMapper, C
}
@Override
public List<CategoryBrand> getCategoryBrandListByBrandId(String brandId) {
return this.list(new LambdaQueryWrapper<CategoryBrand>().eq(CategoryBrand::getBrandId, brandId));
public List<CategoryBrand> getCategoryBrandListByBrandId(List<String> brandId) {
return this.list(new LambdaQueryWrapper<CategoryBrand>().in(CategoryBrand::getBrandId, brandId));
}
@Override

View File

@@ -119,6 +119,13 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
@Autowired
private Cache<GoodsVO> cache;
@Override
public List<Goods> getByBrandIds(List<String> brandIds) {
LambdaQueryWrapper<Goods> lambdaQueryWrapper = new LambdaQueryWrapper<Goods> ();
lambdaQueryWrapper.in(Goods::getBrandId,brandIds);
return list(lambdaQueryWrapper);
}
@Override
public void underStoreGoods(String storeId) {
//获取商品ID列表

View File

@@ -43,7 +43,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -64,7 +63,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
* 缓存
*/
@Autowired
private Cache<GoodsSku> cache;
private Cache cache;
/**
* 分类
*/
@@ -75,11 +74,6 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
*/
@Autowired
private GoodsGalleryService goodsGalleryService;
/**
* 缓存
*/
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* rocketMq
*/
@@ -195,7 +189,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
@Override
public GoodsSku getGoodsSkuByIdFromCache(String id) {
//获取缓存中的sku
GoodsSku goodsSku = cache.get(GoodsSkuService.getCacheKeys(id));
GoodsSku goodsSku = (GoodsSku) cache.get(GoodsSkuService.getCacheKeys(id));
//如果缓存中没有信息,则查询数据库,然后写入缓存
if (goodsSku == null) {
goodsSku = this.getById(id);
@@ -206,14 +200,14 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
}
//获取商品库存
String quantity = stringRedisTemplate.opsForValue().get(GoodsSkuService.getStockCacheKey(id));
Integer integer = (Integer) cache.get(GoodsSkuService.getStockCacheKey(id));
//库存不为空
if (StrUtil.isNotEmpty(quantity)) {
if (integer != null) {
//库存与缓存中不一致,
if (!goodsSku.getQuantity().equals(Convert.toInt(quantity))) {
if (!goodsSku.getQuantity().equals(integer)) {
//写入最新的库存信息
goodsSku.setQuantity(Convert.toInt(quantity));
goodsSku.setQuantity(integer);
cache.put(GoodsSkuService.getCacheKeys(goodsSku.getId()), goodsSku);
}
}
@@ -408,7 +402,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
goodsSku.setQuantity(quantity);
this.update(new LambdaUpdateWrapper<GoodsSku>().eq(GoodsSku::getId, skuId).set(GoodsSku::getQuantity, quantity));
cache.put(GoodsSkuService.getCacheKeys(skuId), goodsSku);
stringRedisTemplate.opsForValue().set(GoodsSkuService.getStockCacheKey(skuId), quantity.toString());
cache.put(GoodsSkuService.getStockCacheKey(skuId), quantity);
//更新商品库存
List<GoodsSku> goodsSkus = new ArrayList<>();
@@ -420,12 +414,12 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
@Override
public Integer getStock(String skuId) {
String cacheKeys = GoodsSkuService.getStockCacheKey(skuId);
String stockStr = stringRedisTemplate.opsForValue().get(cacheKeys);
if (stockStr != null) {
return Convert.toInt(stockStr);
Integer stock = (Integer) cache.get(cacheKeys);
if (stock != null) {
return stock;
} else {
GoodsSku goodsSku = getGoodsSkuByIdFromCache(skuId);
stringRedisTemplate.opsForValue().set(cacheKeys, goodsSku.getQuantity().toString());
cache.put(cacheKeys, goodsSku.getQuantity());
return goodsSku.getQuantity();
}
}
@@ -497,7 +491,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
*
* @param goods 商品信息
*/
private void generateEs(Goods goods) {
public void generateEs(Goods goods) {
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.GENERATOR_GOODS_INDEX.name();
//发送mq消息
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(goods), RocketmqSendCallbackBuilder.commonCallback());
@@ -536,7 +530,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
}
goodsSku.setGoodsType(goods.getGoodsType());
skus.add(goodsSku);
stringRedisTemplate.opsForValue().set(GoodsSkuService.getStockCacheKey(goodsSku.getId()), goodsSku.getQuantity().toString());
cache.put(GoodsSkuService.getStockCacheKey(goodsSku.getId()), goodsSku.getQuantity());
}
this.saveBatch(skus);
return skus;

View File

@@ -1,14 +1,14 @@
package cn.lili.modules.order.cart.entity.dto;
import cn.lili.modules.member.entity.dos.MemberAddress;
import cn.lili.modules.order.cart.entity.enums.SuperpositionPromotionEnum;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.order.order.entity.vo.OrderVO;
import cn.lili.modules.order.order.entity.vo.ReceiptVO;
import cn.lili.modules.order.cart.entity.enums.CartTypeEnum;
import cn.lili.modules.order.cart.entity.enums.SuperpositionPromotionEnum;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.cart.entity.vo.PriceDetailVO;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.order.order.entity.vo.OrderVO;
import cn.lili.modules.order.order.entity.vo.ReceiptVO;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.vos.MemberCouponVO;
import io.swagger.annotations.ApiModelProperty;
@@ -19,6 +19,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 购物车视图
@@ -147,4 +148,16 @@ public class TradeDTO implements Serializable {
public TradeDTO() {
this(CartTypeEnum.CART);
}
/**
* 过滤购物车中已选择的sku
*
* @return
*/
public List<CartSkuVO> getCheckedSkuList() {
if (skuList != null && !skuList.isEmpty()) {
return skuList.stream().filter(CartSkuVO::getChecked).collect(Collectors.toList());
}
return skuList;
}
}

View File

@@ -33,4 +33,8 @@ public enum CartTypeEnum {
*/
KANJIA;
public String getPrefix() {
return "{" + this.name() + "}_";
}
}

View File

@@ -1,30 +0,0 @@
package cn.lili.modules.order.cart.entity.enums;
/**
* 交易缓存枚举
*
* @author Chopper
* @since 2020-03-25 2:30 下午
*/
public enum TradeCacheEnum {
//================交易=================
/**
* 拼团
*/
PINTUAN,
/**
* 购物车原始数据
*/
CART_DATA,
/**
* 立即购买购物车原始数据
*/
BUY_NOW_CART_DATA;
public String getPrefix() {
return "{" + this.name() + "}_";
}
}

View File

@@ -103,7 +103,7 @@ public class CouponRender implements CartRenderStep {
if (memberCoupon == null) {
return;
}
List<CartSkuVO> filterSku = filterSkuVo(tradeDTO.getSkuList(), memberCoupon);
List<CartSkuVO> filterSku = filterSkuVo(tradeDTO.getCheckedSkuList(), memberCoupon);
if (filterSku == null || filterSku.isEmpty()) {
tradeDTO.getCantUseCoupons().add(new MemberCouponVO(memberCoupon,
"购物车中没有满足优惠券使用范围的优惠券"));

View File

@@ -11,13 +11,13 @@ import cn.lili.common.utils.CurrencyUtil;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.member.entity.dos.MemberAddress;
import cn.lili.modules.order.cart.entity.dto.MemberCouponDTO;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.CartTypeEnum;
import cn.lili.modules.order.cart.entity.enums.DeliveryMethodEnum;
import cn.lili.modules.order.cart.entity.enums.TradeCacheEnum;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.cart.entity.vo.TradeParams;
@@ -92,6 +92,11 @@ public class CartServiceImpl implements CartService {
*/
@Autowired
private EsGoodsSearchService esGoodsSearchService;
/**
* ES商品
*/
@Autowired
private GoodsService goodsService;
/**
* 拼团
*/
@@ -197,17 +202,12 @@ public class CartServiceImpl implements CartService {
*/
private String getOriginKey(CartTypeEnum cartTypeEnum) {
String cacheKey = "";
//如果会员登录了则要以会员id为key
AuthUser currentUser = UserContext.getCurrentUser();
if (cartTypeEnum.equals(CartTypeEnum.CART)) {
cacheKey = TradeCacheEnum.CART_DATA.getPrefix() + currentUser.getId();
} else if (cartTypeEnum.equals(CartTypeEnum.BUY_NOW)) {
cacheKey = TradeCacheEnum.BUY_NOW_CART_DATA.getPrefix() + currentUser.getId();
} else if (cartTypeEnum.equals(CartTypeEnum.PINTUAN)) {
cacheKey = TradeCacheEnum.PINTUAN.getPrefix() + currentUser.getId();
//缓存key默认使用购物车
if (cartTypeEnum != null) {
AuthUser currentUser = UserContext.getCurrentUser();
return cartTypeEnum.getPrefix() + currentUser.getId();
}
return cacheKey;
throw new ServiceException(ResultCode.ERROR);
}
@Override
@@ -689,6 +689,8 @@ public class CartServiceImpl implements CartService {
cartSkuVO.setUtilPrice(promotionGoods.getPrice());
cartSkuVO.setPurchasePrice(promotionGoods.getPrice());
} else {
//如果拼团活动被异常处理则在这里安排mq重新写入商品索引
goodsSkuService.generateEs(goodsService.getById(cartSkuVO.getGoodsSku().getGoodsId()));
throw new ServiceException(ResultCode.CART_PINTUAN_NOT_EXIST_ERROR);
}
//检测拼团限购数量

View File

@@ -99,8 +99,7 @@ public class OrderSearchParams extends PageVO {
//关键字查询
if (StrUtil.isNotEmpty(keywords)) {
wrapper.like("o.sn", keywords);
wrapper.like("oi.goods_name", keywords);
wrapper.like("o.sn", keywords).or().like("oi.goods_name", keywords);
}
//按卖家查询
wrapper.eq(StrUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), "o.store_id", UserContext.getCurrentUser().getStoreId());

View File

@@ -339,7 +339,7 @@ public class SeckillServiceImpl extends ServiceImpl<SeckillMapper, Seckill> impl
int sameNum = this.count(queryWrapper);
//当前时间段是否存在同类活动
if (sameNum > 0) {
throw new ServiceException("当前时间内已存在同类活动:" + seckill.getStartTime());
throw new ServiceException(ResultCode.PROMOTION_SAME_ACTIVE_EXIST);
}
}
}

View File

@@ -18,6 +18,16 @@ import java.util.Map;
**/
public interface EsGoodsIndexService {
/**
* 全局索引初始化
*/
void init();
/**
* 获取es生成索引进度
* @return
*/
Map<String, Integer> getProgress();
/**
* 添加商品索引
*

View File

@@ -2,6 +2,8 @@ package cn.lili.modules.search.serviceimpl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import cn.hutool.json.JSONObject;
@@ -9,14 +11,17 @@ import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.elasticsearch.BaseElasticsearchService;
import cn.lili.elasticsearch.EsSuffix;
import cn.lili.elasticsearch.config.ElasticsearchProperties;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dos.GoodsWords;
import cn.lili.modules.goods.entity.dos.*;
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.entity.enums.GoodsWordsTypeEnum;
import cn.lili.modules.goods.service.GoodsWordsService;
import cn.lili.modules.goods.service.*;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dto.BasePromotion;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
@@ -27,6 +32,8 @@ import cn.lili.modules.search.entity.dto.EsGoodsSearchDTO;
import cn.lili.modules.search.repository.EsGoodsIndexRepository;
import cn.lili.modules.search.service.EsGoodsIndexService;
import cn.lili.modules.search.service.EsGoodsSearchService;
import cn.lili.modules.store.entity.dos.StoreGoodsLabel;
import cn.lili.modules.store.service.StoreGoodsLabelService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.IterableUtil;
@@ -78,9 +85,111 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
private GoodsWordsService goodsWordsService;
@Autowired
private PromotionService promotionService;
@Autowired
private GoodsSkuService goodsSkuService;
@Autowired
private GoodsService goodsService;
@Autowired
private BrandService brandService;
@Autowired
private CategoryService categoryService;
@Autowired
private StoreGoodsLabelService storeGoodsLabelService;
@Autowired
private Cache<Object> cache;
@Override
public void init() {
//获取索引任务标识
Boolean flag = (Boolean) cache.get(CachePrefix.INIT_INDEX_FLAG.getPrefix());
//为空则默认写入没有任务
if (flag == null) {
cache.put(CachePrefix.INIT_INDEX_FLAG.getPrefix(), false);
}
//有正在初始化的任务,则提示异常
if (Boolean.TRUE.equals(flag)) {
throw new ServiceException(ResultCode.INDEX_BUILDING);
}
//初始化标识
cache.put(CachePrefix.INIT_INDEX_PROCESS.getPrefix(), null);
cache.put(CachePrefix.INIT_INDEX_FLAG.getPrefix(), true);
ThreadUtil.execAsync(() -> {
try {
//查询商品信息
LambdaQueryWrapper<GoodsSku> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(GoodsSku::getIsAuth, GoodsAuthEnum.PASS.name());
queryWrapper.eq(GoodsSku::getMarketEnable, GoodsStatusEnum.UPPER.name());
List<GoodsSku> list = goodsSkuService.list(queryWrapper);
List<EsGoodsIndex> esGoodsIndices = new ArrayList<>();
//库存锁是在redis做的所以生成索引同时更新一下redis中的库存数量
for (GoodsSku goodsSku : list) {
Goods goods = goodsService.getById(goodsSku.getGoodsId());
//如果出现极端情况有sku没有与之匹配的商品则跳过
if (goods == null) {
continue;
}
EsGoodsIndex index = new EsGoodsIndex(goodsSku);
//商品参数索引
if (goods.getParams() != null && !goods.getParams().isEmpty()) {
List<GoodsParamsDTO> goodsParamDTOS = JSONUtil.toList(goods.getParams(), GoodsParamsDTO.class);
index = new EsGoodsIndex(goodsSku, goodsParamDTOS);
}
//商品分类索引
if (goods.getCategoryPath() != null) {
List<Category> categories = categoryService.listByIdsOrderByLevel(Arrays.asList(goods.getCategoryPath().split(",")));
if (!categories.isEmpty()) {
index.setCategoryNamePath(ArrayUtil.join(categories.stream().map(Category::getName).toArray(), ","));
}
}
//商品品牌索引
Brand brand = brandService.getById(goods.getBrandId());
if (brand != null) {
index.setBrandName(brand.getName());
index.setBrandUrl(brand.getLogo());
}
//店铺分类索引
if (goods.getStoreCategoryPath() != null && CharSequenceUtil.isNotEmpty(goods.getStoreCategoryPath())) {
List<StoreGoodsLabel> storeGoodsLabels = storeGoodsLabelService.listByStoreIds(Arrays.asList(goods.getStoreCategoryPath().split(",")));
if (!storeGoodsLabels.isEmpty()) {
index.setStoreCategoryNamePath(ArrayUtil.join(storeGoodsLabels.stream().map(StoreGoodsLabel::getLabelName).toArray(), ","));
}
}
//促销索引
Map<String, Object> goodsCurrentPromotionMap = promotionService.getGoodsCurrentPromotionMap(index);
index.setPromotionMap(goodsCurrentPromotionMap);
esGoodsIndices.add(index);
cache.put(GoodsSkuService.getStockCacheKey(goodsSku.getId()), goodsSku.getQuantity());
}
//初始化商品索引
this.initIndex(esGoodsIndices);
} catch (Exception e) {
log.error("商品索引生成异常:", e);
//如果出现异常,则将进行中的任务标识取消掉,打印日志
cache.put(CachePrefix.INIT_INDEX_PROCESS.getPrefix(), null);
cache.put(CachePrefix.INIT_INDEX_FLAG.getPrefix(), false);
}
});
}
@Override
public Map<String, Integer> getProgress() {
Map<String, Integer> map = (Map<String, Integer>) cache.get(CachePrefix.INIT_INDEX_PROCESS.getPrefix());
if (map == null) {
return null;
}
Boolean flag = (Boolean) cache.get(CachePrefix.INIT_INDEX_FLAG.getPrefix());
map.put("flag", Boolean.TRUE.equals(flag) ? 1 : 0);
return map;
}
@Override
public void addIndex(EsGoodsIndex goods) {
try {

View File

@@ -159,7 +159,7 @@ public class EsGoodsSearchServiceImpl implements EsGoodsSearchService {
String categoryNamePath = categoryPath;
if (!categoryBuckets.isEmpty()) {
if (!categoryNameBuckets.isEmpty()) {
categoryNamePath = categoryNameBuckets.get(0).getKey().toString();
}
String[] split = ArrayUtil.distinct(categoryPath.split(","));
@@ -187,6 +187,10 @@ public class EsGoodsSearchServiceImpl implements EsGoodsSearchService {
if (brandBuckets != null && !brandBuckets.isEmpty()) {
for (int i = 0; i < brandBuckets.size(); i++) {
String brandId = brandBuckets.get(i).getKey().toString();
//当商品品牌id为0时代表商品没有选择品牌所以过滤掉品牌选择器
if (brandId.equals("0")) {
continue;
}
if (CharSequenceUtil.isNotEmpty(goodsSearch.getBrandId())) {
List<String> brandList = Arrays.asList(goodsSearch.getBrandId().split("@"));
if (brandList.contains(brandId)) {

View File

@@ -20,7 +20,7 @@ public interface VerificationService {
* @return 校验对象
* @throws IOException 校验错误
*/
Map<String, Object> createVerification(VerificationEnums verificationEnums, String uuid) throws IOException;
Map<String, Object> createVerification(VerificationEnums verificationEnums, String uuid);
/**
* 预校验

View File

@@ -17,7 +17,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
@@ -51,7 +50,7 @@ public class VerificationServiceImpl implements VerificationService {
* @return 验证码参数
*/
@Override
public Map<String, Object> createVerification(VerificationEnums verificationEnums, String uuid) throws IOException {
public Map<String, Object> createVerification(VerificationEnums verificationEnums, String uuid) {
if (uuid == null) {
throw new ServiceException(ResultCode.ILLEGAL_REQUEST_ERROR);
@@ -97,8 +96,7 @@ public class VerificationServiceImpl implements VerificationService {
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
log.error("创建校验错误", e);
return null;
throw new ServiceException(ResultCode.ERROR);
}
}
@@ -136,16 +134,16 @@ public class VerificationServiceImpl implements VerificationService {
public boolean preCheck(Integer xPos, String uuid, VerificationEnums verificationEnums) {
Integer randomX = (Integer) cache.get(cacheKey(verificationEnums, uuid));
if (randomX == null) {
return false;
throw new ServiceException(ResultCode.VERIFICATION_CODE_INVALID);
}
log.debug("{}{}", randomX, xPos);
//验证结果
if (Math.abs(randomX - xPos) < verificationCodeProperties.getFaultTolerant()) {
//验证结果正确 && 删除标记成功
if (Math.abs(randomX - xPos) < verificationCodeProperties.getFaultTolerant() && cache.remove(cacheKey(verificationEnums, uuid))) {
//验证成功,则记录验证结果 验证有效时间与验证码创建有效时间一致
cache.put(cacheResult(verificationEnums, uuid), true, verificationCodeProperties.getEffectiveTime());
return true;
}
return false;
throw new ServiceException(ResultCode.VERIFICATION_ERROR);
}
/**
@@ -157,13 +155,11 @@ public class VerificationServiceImpl implements VerificationService {
*/
@Override
public boolean check(String uuid, VerificationEnums verificationEnums) {
Object object = cache.get(cacheResult(verificationEnums, uuid));
if (object == null) {
return false;
} else {
cache.remove(cacheResult(verificationEnums, uuid));
//如果有校验标记,则返回校验结果
if (cache.remove(cacheResult(verificationEnums, uuid))) {
return true;
}
throw new ServiceException(ResultCode.VERIFICATION_CODE_INVALID);
}
/**