diff --git a/README.md b/README.md index 02c67ae5..6e5ea9db 100644 --- a/README.md +++ b/README.md @@ -43,21 +43,21 @@ https://docs.pickmall.cn ### 💧 开源商城项目地址(gitee) -**Java后台(商城所有API)**:https://gitee.com/beijing_hongye_huicheng/lilishop.git +**API(商城所有API)**:https://gitee.com/beijing_hongye_huicheng/lilishop.git **UI(商城管理端/商家端/买家PC端)**: https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git -**Uni-app(商城移动端,支持小程序/APP/H5)**:https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git +**uniapp(商城移动端,支持小程序/APP/H5)**:https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git **docker一键部署(商城部署脚本)**:https://gitee.com/beijing_hongye_huicheng/docker.git ### 💧 开源商城项目地址(github) -**Java后台(商城所有API)**:https://github.com/hongyehuicheng/lilishop.git +**API(商城所有API)**:https://github.com/hongyehuicheng/lilishop.git **UI(商城管理端/商家端/买家PC端)**: https://github.com/hongyehuicheng/lilishop-ui.git -**Uni-app(商城移动端,支持小程序/APP/H5)**:https://github.com/hongyehuicheng/lilishop-uniapp.git +**uniapp(商城移动端,支持小程序/APP/H5)**:https://github.com/hongyehuicheng/lilishop-uniapp.git **docker一键部署(商城部署脚本)**:https://github.com/hongyehuicheng/docker.git diff --git a/admin/src/main/resources/logback-spring.xml b/admin/src/main/resources/logback-spring.xml new file mode 100644 index 00000000..8e2f8cac --- /dev/null +++ b/admin/src/main/resources/logback-spring.xml @@ -0,0 +1,41 @@ + + + + + + + + + + ${APP_NAME} + + + + ${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log + 30 + + + ${FILE_LOG_PATTERN} + + + + + + + 127.0.0.1:4560 + + + + UTC + + + + {"appName":"${APP_NAME}"} + + + + + + + + \ No newline at end of file diff --git a/buyer-api/src/main/java/cn/lili/controller/passport/MemberBuyerController.java b/buyer-api/src/main/java/cn/lili/controller/passport/MemberBuyerController.java index d81bc53e..e49bf29c 100644 --- a/buyer-api/src/main/java/cn/lili/controller/passport/MemberBuyerController.java +++ b/buyer-api/src/main/java/cn/lili/controller/passport/MemberBuyerController.java @@ -1,8 +1,6 @@ package cn.lili.controller.passport; -import cn.lili.common.enums.ResultCode; import cn.lili.common.enums.ResultUtil; -import cn.lili.common.exception.ServiceException; import cn.lili.common.vo.ResultMessage; import cn.lili.modules.member.entity.dos.Member; import cn.lili.modules.member.entity.dto.MemberEditDTO; @@ -47,11 +45,8 @@ public class MemberBuyerController { public ResultMessage userLogin(@NotNull(message = "用户名不能为空") @RequestParam String username, @NotNull(message = "密码不能为空") @RequestParam String password, @RequestHeader String uuid) { - if (verificationService.check(uuid, VerificationEnums.LOGIN)) { - return ResultUtil.data(this.memberService.usernameLogin(username, password)); - } else { - throw new ServiceException(ResultCode.VERIFICATION_ERROR); - } + verificationService.check(uuid, VerificationEnums.LOGIN); + return ResultUtil.data(this.memberService.usernameLogin(username, password)); } @ApiOperation(value = "短信登录接口") @@ -63,11 +58,8 @@ public class MemberBuyerController { public ResultMessage smsLogin(@NotNull(message = "手机号为空") @RequestParam String mobile, @NotNull(message = "验证码为空") @RequestParam String code, @RequestHeader String uuid) { - if (smsUtil.verifyCode(mobile, VerificationEnums.LOGIN, uuid, code)) { - return ResultUtil.data(memberService.mobilePhoneLogin(mobile)); - } else { - throw new ServiceException(ResultCode.VERIFICATION_SMS_ERROR); - } + smsUtil.verifyCode(mobile, VerificationEnums.LOGIN, uuid, code); + return ResultUtil.data(memberService.mobilePhoneLogin(mobile)); } @ApiOperation(value = "注册用户") @@ -84,12 +76,9 @@ public class MemberBuyerController { @RequestHeader String uuid, @NotNull(message = "验证码不能为空") @RequestParam String code) { - boolean result = smsUtil.verifyCode(mobilePhone, VerificationEnums.REGISTER, uuid, code); - if (result) { - return ResultUtil.data(memberService.register(username, password, mobilePhone)); - } else { - throw new ServiceException(ResultCode.VERIFICATION_SMS_ERROR); - } + smsUtil.verifyCode(mobilePhone, VerificationEnums.REGISTER, uuid, code); + return ResultUtil.data(memberService.register(username, password, mobilePhone)); + } @ApiOperation(value = "获取当前登录用户接口") @@ -109,13 +98,11 @@ public class MemberBuyerController { @NotNull(message = "验证码为空") @RequestParam String code, @RequestHeader String uuid) { //校验短信验证码是否正确 - if (smsUtil.verifyCode(mobile, VerificationEnums.FIND_USER, uuid, code)) { - //校验是否通过手机号可获取会员,存在则将会员信息存入缓存,有效时间3分钟 - if (memberService.findByMobile(uuid, mobile)) { - return ResultUtil.success(); - } - } - throw new ServiceException(ResultCode.VERIFICATION_ERROR); + smsUtil.verifyCode(mobile, VerificationEnums.FIND_USER, uuid, code); + //校验是否通过手机号可获取会员,存在则将会员信息存入缓存,有效时间3分钟 + memberService.findByMobile(uuid, mobile); + + return ResultUtil.success(); } @ApiOperation(value = "修改密码") diff --git a/buyer-api/src/main/resources/application.yml b/buyer-api/src/main/resources/application.yml index b33e38c7..9ed3cc2a 100644 --- a/buyer-api/src/main/resources/application.yml +++ b/buyer-api/src/main/resources/application.yml @@ -121,7 +121,7 @@ spring: props: #是否打印逻辑SQL语句和实际SQL语句,建议调试时打印,在生产环境关闭 sql: - show: false + show: true # 忽略TOKEN 鉴权 的url ignored: diff --git a/common-api/src/main/java/cn/lili/controller/common/SliderImageController.java b/common-api/src/main/java/cn/lili/controller/common/SliderImageController.java index 640ffec9..cdb6ba5c 100644 --- a/common-api/src/main/java/cn/lili/controller/common/SliderImageController.java +++ b/common-api/src/main/java/cn/lili/controller/common/SliderImageController.java @@ -1,12 +1,10 @@ package cn.lili.controller.common; import cn.lili.cache.limit.annotation.LimitPoint; -import cn.lili.common.enums.ResultCode; -import cn.lili.common.exception.ServiceException; import cn.lili.common.enums.ResultUtil; +import cn.lili.common.vo.ResultMessage; import cn.lili.modules.verification.enums.VerificationEnums; import cn.lili.modules.verification.service.VerificationService; -import cn.lili.common.vo.ResultMessage; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -32,14 +30,8 @@ public class SliderImageController { @GetMapping("/{verificationEnums}") @ApiOperation(value = "获取校验接口,一分钟同一个ip请求10次") public ResultMessage getSliderImage(@RequestHeader String uuid, @PathVariable VerificationEnums verificationEnums) { - try { - return ResultUtil.data(verificationService.createVerification(verificationEnums, uuid)); - } catch (ServiceException e) { - throw e; - } catch (Exception e) { - log.error("获取校验接口错误", e); - throw new ServiceException(ResultCode.VERIFICATION_EXIST); - } + return ResultUtil.data(verificationService.createVerification(verificationEnums, uuid)); + } @LimitPoint(name = "slider_image", key = "verification_pre_check", limit = 600) diff --git a/common-api/src/main/java/cn/lili/controller/common/SmsController.java b/common-api/src/main/java/cn/lili/controller/common/SmsController.java index 70f5bfab..d74b25dc 100644 --- a/common-api/src/main/java/cn/lili/controller/common/SmsController.java +++ b/common-api/src/main/java/cn/lili/controller/common/SmsController.java @@ -2,12 +2,11 @@ package cn.lili.controller.common; import cn.lili.cache.limit.annotation.LimitPoint; import cn.lili.common.enums.ResultCode; -import cn.lili.common.exception.ServiceException; -import cn.lili.modules.system.sms.SmsUtil; import cn.lili.common.enums.ResultUtil; +import cn.lili.common.vo.ResultMessage; +import cn.lili.modules.system.sms.SmsUtil; import cn.lili.modules.verification.enums.VerificationEnums; import cn.lili.modules.verification.service.VerificationService; -import cn.lili.common.vo.ResultMessage; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -42,11 +41,8 @@ public class SmsController { @RequestHeader String uuid, @PathVariable String mobile, @PathVariable VerificationEnums verificationEnums) { - if (verificationService.check(uuid, verificationEnums)) { - smsUtil.sendSmsCode(mobile, verificationEnums, uuid); - return ResultUtil.success(ResultCode.VERIFICATION_SEND_SUCCESS); - } else { - throw new ServiceException(ResultCode.VERIFICATION_SMS_EXPIRED_ERROR); - } + verificationService.check(uuid, verificationEnums); + smsUtil.sendSmsCode(mobile, verificationEnums, uuid); + return ResultUtil.success(ResultCode.VERIFICATION_SEND_SUCCESS); } } diff --git a/common-api/src/main/resources/application.yml b/common-api/src/main/resources/application.yml index 1157b9bf..fb53aa1c 100644 --- a/common-api/src/main/resources/application.yml +++ b/common-api/src/main/resources/application.yml @@ -118,7 +118,7 @@ spring: props: #是否打印逻辑SQL语句和实际SQL语句,建议调试时打印,在生产环境关闭 sql: - show: false + show: true # 忽略鉴权url ignored: diff --git a/config/application.yml b/config/application.yml index e3e81029..c729b183 100644 --- a/config/application.yml +++ b/config/application.yml @@ -182,7 +182,6 @@ mybatis-plus: # 日志 logging: - config: classpath:logback-spring.xml # 输出级别 level: cn.lili: info @@ -230,11 +229,11 @@ lili: system: isDemoSite: false isTestModel: true -# 脱敏级别: -# 0:不做脱敏处理 -# 1:管理端用户手机号等信息脱敏 -# 2:商家端信息脱敏(为2时,表示管理端,商家端同时脱敏) -# sensitiveLevel: 2 + # 脱敏级别: + # 0:不做脱敏处理 + # 1:管理端用户手机号等信息脱敏 + # 2:商家端信息脱敏(为2时,表示管理端,商家端同时脱敏) + # sensitiveLevel: 2 statistics: # 在线人数统计 X 小时。这里设置48,即统计过去48小时每小时在线人数 diff --git a/consumer/src/main/resources/application.yml b/consumer/src/main/resources/application.yml index 1ec5a786..65dffa3c 100644 --- a/consumer/src/main/resources/application.yml +++ b/consumer/src/main/resources/application.yml @@ -121,7 +121,7 @@ spring: props: #是否打印逻辑SQL语句和实际SQL语句,建议调试时打印,在生产环境关闭 sql: - show: false + show: true # 忽略鉴权url ignored: diff --git a/framework/src/main/java/cn/lili/cache/Cache.java b/framework/src/main/java/cn/lili/cache/Cache.java index d71bc646..7bd4d481 100644 --- a/framework/src/main/java/cn/lili/cache/Cache.java +++ b/framework/src/main/java/cn/lili/cache/Cache.java @@ -89,7 +89,7 @@ public interface Cache { * * @param key 缓存key */ - void remove(Object key); + Boolean remove(Object key); /** * 删除 diff --git a/framework/src/main/java/cn/lili/cache/impl/RedisCache.java b/framework/src/main/java/cn/lili/cache/impl/RedisCache.java index b16d0405..ade80a68 100644 --- a/framework/src/main/java/cn/lili/cache/impl/RedisCache.java +++ b/framework/src/main/java/cn/lili/cache/impl/RedisCache.java @@ -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); } /** diff --git a/framework/src/main/java/cn/lili/common/enums/ResultCode.java b/framework/src/main/java/cn/lili/common/enums/ResultCode.java index 90b3703b..accc1077 100644 --- a/framework/src/main/java/cn/lili/common/enums/ResultCode.java +++ b/framework/src/main/java/cn/lili/common/enums/ResultCode.java @@ -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; diff --git a/framework/src/main/java/cn/lili/common/exception/ServiceException.java b/framework/src/main/java/cn/lili/common/exception/ServiceException.java index 3b7b3fc5..feb98e6d 100644 --- a/framework/src/main/java/cn/lili/common/exception/ServiceException.java +++ b/framework/src/main/java/cn/lili/common/exception/ServiceException.java @@ -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 = "网络错误,请稍后重试!"; /** * 异常消息 diff --git a/framework/src/main/java/cn/lili/common/utils/ThreadPoolUtil.java b/framework/src/main/java/cn/lili/common/utils/ThreadPoolUtil.java index 17f87182..5a62281a 100644 --- a/framework/src/main/java/cn/lili/common/utils/ThreadPoolUtil.java +++ b/framework/src/main/java/cn/lili/common/utils/ThreadPoolUtil.java @@ -24,7 +24,10 @@ public class ThreadPoolUtil { */ private static final BlockingQueue BQUEUE = new ArrayBlockingQueue(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() { diff --git a/framework/src/main/java/cn/lili/modules/goods/entity/dos/Goods.java b/framework/src/main/java/cn/lili/modules/goods/entity/dos/Goods.java index e890b200..9cff3528 100644 --- a/framework/src/main/java/cn/lili/modules/goods/entity/dos/Goods.java +++ b/framework/src/main/java/cn/lili/modules/goods/entity/dos/Goods.java @@ -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) diff --git a/framework/src/main/java/cn/lili/modules/goods/service/CategoryBrandService.java b/framework/src/main/java/cn/lili/modules/goods/service/CategoryBrandService.java index 57a776bc..32f84616 100644 --- a/framework/src/main/java/cn/lili/modules/goods/service/CategoryBrandService.java +++ b/framework/src/main/java/cn/lili/modules/goods/service/CategoryBrandService.java @@ -35,7 +35,7 @@ public interface CategoryBrandService extends IService { * @param brandId 品牌ID * @return 分类品牌关联信息 */ - List getCategoryBrandListByBrandId(String brandId); + List getCategoryBrandListByBrandId(List brandId); /** * 保存分类品牌关系 diff --git a/framework/src/main/java/cn/lili/modules/goods/service/GoodsService.java b/framework/src/main/java/cn/lili/modules/goods/service/GoodsService.java index 2c6e03fb..dbf17a60 100644 --- a/framework/src/main/java/cn/lili/modules/goods/service/GoodsService.java +++ b/framework/src/main/java/cn/lili/modules/goods/service/GoodsService.java @@ -20,6 +20,13 @@ import java.util.List; public interface GoodsService extends IService { + /** + * 根据品牌获取商品 + * + * @param brandIds 品牌ids + */ + List getByBrandIds(List brandIds); + /** * 下架所有商家商品 * diff --git a/framework/src/main/java/cn/lili/modules/goods/service/GoodsSkuService.java b/framework/src/main/java/cn/lili/modules/goods/service/GoodsSkuService.java index a79e547c..022e7917 100644 --- a/framework/src/main/java/cn/lili/modules/goods/service/GoodsSkuService.java +++ b/framework/src/main/java/cn/lili/modules/goods/service/GoodsSkuService.java @@ -143,6 +143,13 @@ public interface GoodsSkuService extends IService { */ void updateGoodsSkuStatus(Goods goods); + /** + * 发送生成ES商品索引 + * + * @param goods 商品信息 + */ + void generateEs(Goods goods); + /** * 更新SKU库存 * diff --git a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/BrandServiceImpl.java b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/BrandServiceImpl.java index 05612b92..9c985a11 100644 --- a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/BrandServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/BrandServiceImpl.java @@ -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 implements @Autowired private CategoryService categoryService; + @Autowired + private GoodsService goodsService; + @Override public IPage getBrandsByPage(BrandPageDTO page) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); @@ -88,7 +93,9 @@ public class BrandServiceImpl extends ServiceImpl implements Brand brand = this.checkExist(brandId); //如果是要禁用,则需要先判定绑定关系 if (Boolean.TRUE.equals(disable)) { - checkoutCategory(brandId); + List ids = new ArrayList<>(); + ids.add(brandId); + checkBind(ids); } brand.setDeleteFlag(disable); return updateById(brand); @@ -96,7 +103,7 @@ public class BrandServiceImpl extends ServiceImpl implements @Override public void deleteBrands(List ids) { - ids.forEach(this::checkoutCategory); + checkBind(ids); this.removeByIds(ids); } @@ -104,16 +111,32 @@ public class BrandServiceImpl extends ServiceImpl implements /** * 校验绑定关系 * - * @param brandId + * @param brandIds */ - private void checkoutCategory(String brandId) { + private void checkBind(List brandIds) { //分了绑定关系查询 - List categoryBrands = categoryBrandService.getCategoryBrandListByBrandId(brandId); + List categoryBrands = categoryBrandService.getCategoryBrandListByBrandId(brandIds); if (!categoryBrands.isEmpty()) { - List brandIds = categoryBrands.stream().map(CategoryBrand::getCategoryId).collect(Collectors.toList()); + List 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 = goodsService.getByBrandIds(brandIds); + if (!goods.isEmpty()) { + List 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 brandIds) { } /** diff --git a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/CategoryBrandServiceImpl.java b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/CategoryBrandServiceImpl.java index 4d0929f3..0762b29b 100644 --- a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/CategoryBrandServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/CategoryBrandServiceImpl.java @@ -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 getCategoryBrandListByBrandId(String brandId) { - return this.list(new LambdaQueryWrapper().eq(CategoryBrand::getBrandId, brandId)); + public List getCategoryBrandListByBrandId(List brandId) { + return this.list(new LambdaQueryWrapper().in(CategoryBrand::getBrandId, brandId)); } @Override diff --git a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsServiceImpl.java b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsServiceImpl.java index af7d8365..08cb2a2d 100644 --- a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsServiceImpl.java @@ -119,6 +119,13 @@ public class GoodsServiceImpl extends ServiceImpl implements @Autowired private Cache cache; + @Override + public List getByBrandIds(List brandIds) { + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper (); + lambdaQueryWrapper.in(Goods::getBrandId,brandIds); + return list(lambdaQueryWrapper); + } + @Override public void underStoreGoods(String storeId) { //获取商品ID列表 diff --git a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsSkuServiceImpl.java b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsSkuServiceImpl.java index 72fd03a7..e56686c4 100644 --- a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsSkuServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsSkuServiceImpl.java @@ -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 i * 缓存 */ @Autowired - private Cache cache; + private Cache cache; /** * 分类 */ @@ -75,11 +74,6 @@ public class GoodsSkuServiceImpl extends ServiceImpl i */ @Autowired private GoodsGalleryService goodsGalleryService; - /** - * 缓存 - */ - @Autowired - private StringRedisTemplate stringRedisTemplate; /** * rocketMq */ @@ -195,7 +189,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl 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 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 i goodsSku.setQuantity(quantity); this.update(new LambdaUpdateWrapper().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 goodsSkus = new ArrayList<>(); @@ -420,12 +414,12 @@ public class GoodsSkuServiceImpl extends ServiceImpl 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 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 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; diff --git a/framework/src/main/java/cn/lili/modules/order/cart/entity/dto/TradeDTO.java b/framework/src/main/java/cn/lili/modules/order/cart/entity/dto/TradeDTO.java index b6286359..5191f9fb 100644 --- a/framework/src/main/java/cn/lili/modules/order/cart/entity/dto/TradeDTO.java +++ b/framework/src/main/java/cn/lili/modules/order/cart/entity/dto/TradeDTO.java @@ -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 getCheckedSkuList() { + if (skuList != null && !skuList.isEmpty()) { + return skuList.stream().filter(CartSkuVO::getChecked).collect(Collectors.toList()); + } + return skuList; + } } diff --git a/framework/src/main/java/cn/lili/modules/order/cart/entity/enums/CartTypeEnum.java b/framework/src/main/java/cn/lili/modules/order/cart/entity/enums/CartTypeEnum.java index 1f273a53..2a6073b7 100644 --- a/framework/src/main/java/cn/lili/modules/order/cart/entity/enums/CartTypeEnum.java +++ b/framework/src/main/java/cn/lili/modules/order/cart/entity/enums/CartTypeEnum.java @@ -33,4 +33,8 @@ public enum CartTypeEnum { */ KANJIA; + public String getPrefix() { + return "{" + this.name() + "}_"; + } + } diff --git a/framework/src/main/java/cn/lili/modules/order/cart/entity/enums/TradeCacheEnum.java b/framework/src/main/java/cn/lili/modules/order/cart/entity/enums/TradeCacheEnum.java deleted file mode 100644 index 3e26d466..00000000 --- a/framework/src/main/java/cn/lili/modules/order/cart/entity/enums/TradeCacheEnum.java +++ /dev/null @@ -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() + "}_"; - } -} diff --git a/framework/src/main/java/cn/lili/modules/order/cart/render/impl/CouponRender.java b/framework/src/main/java/cn/lili/modules/order/cart/render/impl/CouponRender.java index cbb9f9f6..ad833422 100644 --- a/framework/src/main/java/cn/lili/modules/order/cart/render/impl/CouponRender.java +++ b/framework/src/main/java/cn/lili/modules/order/cart/render/impl/CouponRender.java @@ -103,7 +103,7 @@ public class CouponRender implements CartRenderStep { if (memberCoupon == null) { return; } - List filterSku = filterSkuVo(tradeDTO.getSkuList(), memberCoupon); + List filterSku = filterSkuVo(tradeDTO.getCheckedSkuList(), memberCoupon); if (filterSku == null || filterSku.isEmpty()) { tradeDTO.getCantUseCoupons().add(new MemberCouponVO(memberCoupon, "购物车中没有满足优惠券使用范围的优惠券")); diff --git a/framework/src/main/java/cn/lili/modules/order/cart/service/CartServiceImpl.java b/framework/src/main/java/cn/lili/modules/order/cart/service/CartServiceImpl.java index 35960d7a..68a94a20 100644 --- a/framework/src/main/java/cn/lili/modules/order/cart/service/CartServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/order/cart/service/CartServiceImpl.java @@ -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); } //检测拼团限购数量 diff --git a/framework/src/main/java/cn/lili/modules/order/order/entity/dto/OrderSearchParams.java b/framework/src/main/java/cn/lili/modules/order/order/entity/dto/OrderSearchParams.java index f32eaf3e..a8add156 100644 --- a/framework/src/main/java/cn/lili/modules/order/order/entity/dto/OrderSearchParams.java +++ b/framework/src/main/java/cn/lili/modules/order/order/entity/dto/OrderSearchParams.java @@ -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()); diff --git a/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/SeckillServiceImpl.java b/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/SeckillServiceImpl.java index c98962ae..c059874a 100644 --- a/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/SeckillServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/SeckillServiceImpl.java @@ -339,7 +339,7 @@ public class SeckillServiceImpl extends ServiceImpl impl int sameNum = this.count(queryWrapper); //当前时间段是否存在同类活动 if (sameNum > 0) { - throw new ServiceException("当前时间内已存在同类活动:" + seckill.getStartTime()); + throw new ServiceException(ResultCode.PROMOTION_SAME_ACTIVE_EXIST); } } } \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/search/service/EsGoodsIndexService.java b/framework/src/main/java/cn/lili/modules/search/service/EsGoodsIndexService.java index a33c8928..f7edeb7e 100644 --- a/framework/src/main/java/cn/lili/modules/search/service/EsGoodsIndexService.java +++ b/framework/src/main/java/cn/lili/modules/search/service/EsGoodsIndexService.java @@ -18,6 +18,16 @@ import java.util.Map; **/ public interface EsGoodsIndexService { + /** + * 全局索引初始化 + */ + void init(); + + /** + * 获取es生成索引进度 + * @return + */ + Map getProgress(); /** * 添加商品索引 * diff --git a/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsIndexServiceImpl.java b/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsIndexServiceImpl.java index 3f8fdfd0..4c343c42 100644 --- a/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsIndexServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsIndexServiceImpl.java @@ -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 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 queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(GoodsSku::getIsAuth, GoodsAuthEnum.PASS.name()); + queryWrapper.eq(GoodsSku::getMarketEnable, GoodsStatusEnum.UPPER.name()); + + List list = goodsSkuService.list(queryWrapper); + List 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 goodsParamDTOS = JSONUtil.toList(goods.getParams(), GoodsParamsDTO.class); + index = new EsGoodsIndex(goodsSku, goodsParamDTOS); + } + //商品分类索引 + if (goods.getCategoryPath() != null) { + List 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 storeGoodsLabels = storeGoodsLabelService.listByStoreIds(Arrays.asList(goods.getStoreCategoryPath().split(","))); + if (!storeGoodsLabels.isEmpty()) { + index.setStoreCategoryNamePath(ArrayUtil.join(storeGoodsLabels.stream().map(StoreGoodsLabel::getLabelName).toArray(), ",")); + } + } + //促销索引 + Map 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 getProgress() { + Map map = (Map) 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 { diff --git a/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsSearchServiceImpl.java b/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsSearchServiceImpl.java index 73792f46..efd86c71 100644 --- a/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsSearchServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsSearchServiceImpl.java @@ -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 brandList = Arrays.asList(goodsSearch.getBrandId().split("@")); if (brandList.contains(brandId)) { diff --git a/framework/src/main/java/cn/lili/modules/verification/service/VerificationService.java b/framework/src/main/java/cn/lili/modules/verification/service/VerificationService.java index 9bd4109d..44c3f836 100644 --- a/framework/src/main/java/cn/lili/modules/verification/service/VerificationService.java +++ b/framework/src/main/java/cn/lili/modules/verification/service/VerificationService.java @@ -20,7 +20,7 @@ public interface VerificationService { * @return 校验对象 * @throws IOException 校验错误 */ - Map createVerification(VerificationEnums verificationEnums, String uuid) throws IOException; + Map createVerification(VerificationEnums verificationEnums, String uuid); /** * 预校验 diff --git a/framework/src/main/java/cn/lili/modules/verification/service/impl/VerificationServiceImpl.java b/framework/src/main/java/cn/lili/modules/verification/service/impl/VerificationServiceImpl.java index 9f35be8c..11652061 100644 --- a/framework/src/main/java/cn/lili/modules/verification/service/impl/VerificationServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/verification/service/impl/VerificationServiceImpl.java @@ -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 createVerification(VerificationEnums verificationEnums, String uuid) throws IOException { + public Map 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); } /** diff --git a/manager-api/src/main/java/cn/lili/controller/other/ElasticsearchController.java b/manager-api/src/main/java/cn/lili/controller/other/ElasticsearchController.java index a4cac7dc..453d1efd 100644 --- a/manager-api/src/main/java/cn/lili/controller/other/ElasticsearchController.java +++ b/manager-api/src/main/java/cn/lili/controller/other/ElasticsearchController.java @@ -1,41 +1,15 @@ package cn.lili.controller.other; -import cn.hutool.core.text.CharSequenceUtil; -import cn.hutool.core.thread.ThreadUtil; -import cn.hutool.core.util.ArrayUtil; -import cn.hutool.json.JSONUtil; import cn.lili.cache.Cache; -import cn.lili.cache.CachePrefix; import cn.lili.common.enums.ResultUtil; import cn.lili.common.vo.ResultMessage; -import cn.lili.modules.goods.entity.dos.Brand; -import cn.lili.modules.goods.entity.dos.Category; -import cn.lili.modules.goods.entity.dos.Goods; -import cn.lili.modules.goods.entity.dos.GoodsSku; -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.service.BrandService; -import cn.lili.modules.goods.service.CategoryService; -import cn.lili.modules.goods.service.GoodsService; -import cn.lili.modules.goods.service.GoodsSkuService; -import cn.lili.modules.promotion.service.PromotionService; -import cn.lili.modules.search.entity.dos.EsGoodsIndex; import cn.lili.modules.search.service.EsGoodsIndexService; -import cn.lili.modules.store.entity.dos.StoreGoodsLabel; -import cn.lili.modules.store.service.StoreGoodsLabelService; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import io.swagger.annotations.Api; -import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; import java.util.Map; /** @@ -48,108 +22,22 @@ import java.util.Map; @RestController @Api(tags = "ES初始化接口") @RequestMapping("/manager/elasticsearch") -@Slf4j public class ElasticsearchController { @Autowired private EsGoodsIndexService esGoodsIndexService; - @Autowired - private GoodsSkuService goodsSkuService; - - @Autowired - private GoodsService goodsService; - - @Autowired - private StringRedisTemplate stringRedisTemplate; - - @Autowired - private PromotionService promotionService; - - @Autowired - private CategoryService categoryService; - - @Autowired - private BrandService brandService; - - @Autowired - private StoreGoodsLabelService storeGoodsLabelService; - @Autowired private Cache cache; @GetMapping public ResultMessage 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)) { - return ResultUtil.error(100000, "当前有任务在执行"); - } - - cache.put(CachePrefix.INIT_INDEX_PROCESS.getPrefix(), null); - cache.put(CachePrefix.INIT_INDEX_FLAG.getPrefix(), true); - ThreadUtil.execAsync(() -> { - try { - //查询商品信息 - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(GoodsSku::getIsAuth, GoodsAuthEnum.PASS.name()); - queryWrapper.eq(GoodsSku::getMarketEnable, GoodsStatusEnum.UPPER.name()); - - List list = goodsSkuService.list(queryWrapper); - List esGoodsIndices = new ArrayList<>(); - //库存锁是在redis做的,所以生成索引,同时更新一下redis中的库存数量 - for (GoodsSku goodsSku : list) { - Goods goods = goodsService.getById(goodsSku.getGoodsId()); - EsGoodsIndex index = new EsGoodsIndex(goodsSku); - if (goods.getParams() != null && !goods.getParams().isEmpty()) { - List goodsParamDTOS = JSONUtil.toList(goods.getParams(), GoodsParamsDTO.class); - index = new EsGoodsIndex(goodsSku, goodsParamDTOS); - } - if (goods.getCategoryPath() != null) { - List 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 storeGoodsLabels = storeGoodsLabelService.listByStoreIds(Arrays.asList(goods.getStoreCategoryPath().split(","))); - if (!storeGoodsLabels.isEmpty()) { - index.setStoreCategoryNamePath(ArrayUtil.join(storeGoodsLabels.stream().map(StoreGoodsLabel::getLabelName).toArray(), ",")); - } - } - Map goodsCurrentPromotionMap = promotionService.getGoodsCurrentPromotionMap(index); - index.setPromotionMap(goodsCurrentPromotionMap); - esGoodsIndices.add(index); - stringRedisTemplate.opsForValue().set(GoodsSkuService.getStockCacheKey(goodsSku.getId()), goodsSku.getQuantity().toString()); - } - //初始化商品索引 - esGoodsIndexService.initIndex(esGoodsIndices); - } catch (Exception e) { - cache.put(CachePrefix.INIT_INDEX_PROCESS.getPrefix(), null); - cache.put(CachePrefix.INIT_INDEX_FLAG.getPrefix(), false); - log.error("初始化索引异常", e); - } - }); + esGoodsIndexService.init(); return ResultUtil.success(); } @GetMapping("/progress") public ResultMessage> getProgress() { - try { - Map map = (Map) cache.get(CachePrefix.INIT_INDEX_PROCESS.getPrefix()); - Boolean flag = (Boolean) cache.get(CachePrefix.INIT_INDEX_FLAG.getPrefix()); - map.put("flag", Boolean.TRUE.equals(flag) ? 1 : 0); - return ResultUtil.data(map); - } catch (Exception e) { - return ResultUtil.data(null); - } + return ResultUtil.data(esGoodsIndexService.getProgress()); } } diff --git a/manager-api/src/main/resources/application.yml b/manager-api/src/main/resources/application.yml index 8db62326..08e14ecd 100644 --- a/manager-api/src/main/resources/application.yml +++ b/manager-api/src/main/resources/application.yml @@ -118,7 +118,7 @@ spring: props: #是否打印逻辑SQL语句和实际SQL语句,建议调试时打印,在生产环境关闭 sql: - show: false + show: true # 忽略鉴权url ignored: diff --git a/manager-api/src/test/java/cn/lili/test/elasticsearch/EsTest.java b/manager-api/src/test/java/cn/lili/test/elasticsearch/EsTest.java index 566a5772..430ad1d7 100644 --- a/manager-api/src/test/java/cn/lili/test/elasticsearch/EsTest.java +++ b/manager-api/src/test/java/cn/lili/test/elasticsearch/EsTest.java @@ -2,6 +2,7 @@ package cn.lili.test.elasticsearch; import cn.hutool.core.util.ReflectUtil; import cn.hutool.json.JSONUtil; +import cn.lili.cache.Cache; import cn.lili.common.vo.PageVO; import cn.lili.modules.goods.entity.dos.GoodsSku; import cn.lili.modules.goods.entity.enums.GoodsAuthEnum; @@ -22,7 +23,6 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.elasticsearch.core.SearchPage; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.test.context.junit.jupiter.SpringExtension; import java.lang.reflect.Field; @@ -52,7 +52,7 @@ class EsTest { private GoodsSkuService goodsSkuService; @Autowired - private StringRedisTemplate stringRedisTemplate; + private Cache cache; @Autowired private PromotionService promotionService; @@ -161,7 +161,7 @@ class EsTest { Map goodsCurrentPromotionMap = promotionService.getGoodsCurrentPromotionMap(index); index.setPromotionMap(goodsCurrentPromotionMap); esGoodsIndices.add(index); - stringRedisTemplate.opsForValue().set(GoodsSkuService.getStockCacheKey(goodsSku.getId()), goodsSku.getQuantity().toString()); + cache.put(GoodsSkuService.getStockCacheKey(goodsSku.getId()), goodsSku.getQuantity()); } esGoodsIndexService.initIndex(esGoodsIndices); Assertions.assertTrue(true); diff --git a/seller-api/src/main/resources/application.yml b/seller-api/src/main/resources/application.yml index 2eb3eebe..95886ca4 100644 --- a/seller-api/src/main/resources/application.yml +++ b/seller-api/src/main/resources/application.yml @@ -118,7 +118,7 @@ spring: props: #是否打印逻辑SQL语句和实际SQL语句,建议调试时打印,在生产环境关闭 sql: - show: false + show: true # 忽略鉴权url ignored: