merge origin master
This commit is contained in:
commit
c85caab197
@ -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
|
||||
|
||||
|
41
admin/src/main/resources/logback-spring.xml
Normal file
41
admin/src/main/resources/logback-spring.xml
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE configuration>
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
|
||||
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
|
||||
<!--应用名称-->
|
||||
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
|
||||
<!--日志文件保存路径-->
|
||||
<springProperty scope="context" name="LOG_FILE_PATH" source="logging.file.path"/>
|
||||
<contextName>${APP_NAME}</contextName>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${FILE_LOG_PATTERN}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!--输出到elk的LOGSTASH-->
|
||||
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
|
||||
<!-- 配置elk日志收集 配饰的是 LOGSTASH 的地址-->
|
||||
<destination>127.0.0.1:4560</destination>
|
||||
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
|
||||
<providers>
|
||||
<timestamp>
|
||||
<timeZone>UTC</timeZone>
|
||||
</timestamp>
|
||||
</providers>
|
||||
<!--自定义字段 区分项目-->
|
||||
<customFields>{"appName":"${APP_NAME}"}</customFields>
|
||||
</encoder>
|
||||
</appender>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="FILE"/>
|
||||
<appender-ref ref="LOGSTASH"/>
|
||||
</root>
|
||||
</configuration>
|
@ -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<Object> 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<Object> 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 = "修改密码")
|
||||
|
@ -121,7 +121,7 @@ spring:
|
||||
props:
|
||||
#是否打印逻辑SQL语句和实际SQL语句,建议调试时打印,在生产环境关闭
|
||||
sql:
|
||||
show: false
|
||||
show: true
|
||||
|
||||
# 忽略TOKEN 鉴权 的url
|
||||
ignored:
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ spring:
|
||||
props:
|
||||
#是否打印逻辑SQL语句和实际SQL语句,建议调试时打印,在生产环境关闭
|
||||
sql:
|
||||
show: false
|
||||
show: true
|
||||
|
||||
# 忽略鉴权url
|
||||
ignored:
|
||||
|
@ -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小时每小时在线人数
|
||||
|
@ -121,7 +121,7 @@ spring:
|
||||
props:
|
||||
#是否打印逻辑SQL语句和实际SQL语句,建议调试时打印,在生产环境关闭
|
||||
sql:
|
||||
show: false
|
||||
show: true
|
||||
|
||||
# 忽略鉴权url
|
||||
ignored:
|
||||
|
@ -89,7 +89,7 @@ public interface Cache<T> {
|
||||
*
|
||||
* @param key 缓存key
|
||||
*/
|
||||
void remove(Object key);
|
||||
Boolean remove(Object key);
|
||||
|
||||
/**
|
||||
* 删除
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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 = "网络错误,请稍后重试!";
|
||||
|
||||
/**
|
||||
* 异常消息
|
||||
|
@ -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() {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
* 保存分类品牌关系
|
||||
|
@ -20,6 +20,13 @@ import java.util.List;
|
||||
public interface GoodsService extends IService<Goods> {
|
||||
|
||||
|
||||
/**
|
||||
* 根据品牌获取商品
|
||||
*
|
||||
* @param brandIds 品牌ids
|
||||
*/
|
||||
List<Goods> getByBrandIds(List<String> brandIds);
|
||||
|
||||
/**
|
||||
* 下架所有商家商品
|
||||
*
|
||||
|
@ -143,6 +143,13 @@ public interface GoodsSkuService extends IService<GoodsSku> {
|
||||
*/
|
||||
void updateGoodsSkuStatus(Goods goods);
|
||||
|
||||
/**
|
||||
* 发送生成ES商品索引
|
||||
*
|
||||
* @param goods 商品信息
|
||||
*/
|
||||
void generateEs(Goods goods);
|
||||
|
||||
/**
|
||||
* 更新SKU库存
|
||||
*
|
||||
|
@ -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) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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列表
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -33,4 +33,8 @@ public enum CartTypeEnum {
|
||||
*/
|
||||
KANJIA;
|
||||
|
||||
public String getPrefix() {
|
||||
return "{" + this.name() + "}_";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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() + "}_";
|
||||
}
|
||||
}
|
@ -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,
|
||||
"购物车中没有满足优惠券使用范围的优惠券"));
|
||||
|
@ -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);
|
||||
}
|
||||
//检测拼团限购数量
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,6 +18,16 @@ import java.util.Map;
|
||||
**/
|
||||
public interface EsGoodsIndexService {
|
||||
|
||||
/**
|
||||
* 全局索引初始化
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* 获取es生成索引进度
|
||||
* @return
|
||||
*/
|
||||
Map<String, Integer> getProgress();
|
||||
/**
|
||||
* 添加商品索引
|
||||
*
|
||||
|
@ -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 {
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
* 预校验
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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<String> 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<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());
|
||||
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);
|
||||
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<Map<String, Integer>> getProgress() {
|
||||
try {
|
||||
Map<String, Integer> map = (Map<String, Integer>) 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());
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ spring:
|
||||
props:
|
||||
#是否打印逻辑SQL语句和实际SQL语句,建议调试时打印,在生产环境关闭
|
||||
sql:
|
||||
show: false
|
||||
show: true
|
||||
|
||||
# 忽略鉴权url
|
||||
ignored:
|
||||
|
@ -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<String, Object> 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);
|
||||
|
@ -118,7 +118,7 @@ spring:
|
||||
props:
|
||||
#是否打印逻辑SQL语句和实际SQL语句,建议调试时打印,在生产环境关闭
|
||||
sql:
|
||||
show: false
|
||||
show: true
|
||||
|
||||
# 忽略鉴权url
|
||||
ignored:
|
||||
|
Loading…
x
Reference in New Issue
Block a user