This commit is contained in:
zhenghao
2022-02-10 20:18:05 +08:00
292 changed files with 2390 additions and 1103 deletions

View File

@@ -15,6 +15,11 @@
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-properties-migrator</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
@@ -30,6 +35,12 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
@@ -67,6 +78,10 @@
<artifactId>HdrHistogram</artifactId>
<groupId>org.hdrhistogram</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
@@ -76,6 +91,12 @@
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-redis</artifactId>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
@@ -91,29 +112,40 @@
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus-version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter-test</artifactId>
<version>2.2.0</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-version}</version>
</dependency>
<!-- Redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Swagger API文档 -->
<!-- https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>${redisson}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- Hutool工具包 -->
<dependency>
@@ -143,6 +175,12 @@
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>${aliyun-version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 阿里云OSS -->
<dependency>
@@ -161,6 +199,16 @@
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>${aliyun-sdk-dysms-version}</version>
<exclusions>
<exclusion>
<artifactId>org.jacoco.agent</artifactId>
<groupId>org.jacoco</groupId>
</exclusion>
<exclusion>
<artifactId>bcprov-jdk15on</artifactId>
<groupId>org.bouncycastle</groupId>
</exclusion>
</exclusions>
</dependency>
<!--脚本编程-->
<dependency>
@@ -172,6 +220,16 @@
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>${rocketmq-version}</version>
<exclusions>
<exclusion>
<artifactId>fastjson</artifactId>
<groupId>com.alibaba</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- token加密 -->
<dependency>
@@ -195,6 +253,12 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 解决版本提示问题 -->
@@ -220,6 +284,18 @@
<artifactId>groovy</artifactId>
<groupId>org.codehaus.groovy</groupId>
</exclusion>
<exclusion>
<artifactId>commons-collections4</artifactId>
<groupId>org.apache.commons</groupId>
</exclusion>
<exclusion>
<artifactId>antlr4-runtime</artifactId>
<groupId>org.antlr</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
@@ -227,6 +303,12 @@
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-namespace</artifactId>
<version>${sharding-jdbc-version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!--druid-->
<dependency>
@@ -248,6 +330,20 @@
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>${alipay-sdk-version}</version>
<exclusions>
<exclusion>
<artifactId>bcprov-jdk15on</artifactId>
<groupId>org.bouncycastle</groupId>
</exclusion>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
<exclusion>
<artifactId>xml-apis</artifactId>
<groupId>xml-apis</groupId>
</exclusion>
</exclusions>
</dependency>
<!--用户端类型处理-->
@@ -272,11 +368,6 @@
<artifactId>logstash-logback-encoder</artifactId>
<version>${logstash-logback-encoder}</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>javax.interceptor</groupId>-->
<!-- <artifactId>javax.interceptor-api</artifactId>-->
<!-- <version>${interceptor-api}</version>-->
<!-- </dependency>-->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
@@ -314,6 +405,12 @@
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>owasp-java-html-sanitizer</artifactId>
<version>${owasp-java-html-sanitizer}</version>
<exclusions>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

View File

@@ -211,6 +211,14 @@ public interface Cache<T> {
* @return 计数器结果
*/
Long incr(String key, long liveTime);
/**
* redis 计数器 累加
* 注到达liveTime之后该次增加取消即自动-1而不是redis值为空
*
* @param key 为累计的key同一key每次调用则值 +1
* @return 计数器结果
*/
Long incr(String key);
//-----------------------------------------------redis计数---------------------------------------------
/**

View File

@@ -4,6 +4,9 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -17,6 +20,7 @@ import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
@@ -27,6 +31,7 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.io.IOException;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
@@ -78,6 +83,7 @@ public class RedisConfig extends CachingConfigurerSupport {
可参考 https://blog.csdn.net/u012240455/article/details/80538540
*/
ParserConfig.getGlobalInstance().addAccept("cn.lili.");
ParserConfig.getGlobalInstance().addAccept("cn.hutool.json.");
return cacheManager;
}
@@ -98,6 +104,12 @@ public class RedisConfig extends CachingConfigurerSupport {
return template;
}
@Bean(destroyMethod = "shutdown")
public RedissonClient redisson() throws IOException {
return Redisson.create(
Config.fromYAML(new ClassPathResource("redisson.yaml").getInputStream()));
}
/**
* 自定义缓存key生成策略默认将使用该策略
*/

View File

@@ -80,7 +80,7 @@ public class RedisCache implements Cache {
@Override
public Boolean remove(Object key) {
return redisTemplate.delete(key);
return redisTemplate.delete(key);
}
/**
@@ -207,13 +207,19 @@ public class RedisCache implements Cache {
RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
Long increment = entityIdCounter.getAndIncrement();
//初始设置过期时间
if ((null == increment || increment == 0) && liveTime > 0) {
if (increment == 0 && liveTime > 0) {
entityIdCounter.expire(liveTime, TimeUnit.SECONDS);
}
return increment;
}
@Override
public Long incr(String key) {
RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
return entityIdCounter.getAndIncrement();
}
/**
* 使用Sorted Set记录keyword
* zincrby命令对于一个Sorted Set存在的就把分数加x(x可自行设定)不存在就创建一个分数为1的成员

View File

@@ -4,6 +4,7 @@ import cn.lili.cache.limit.enums.LimitTypeEnums;
import cn.lili.cache.limit.annotation.LimitPoint;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.utils.IpUtils;
import com.google.common.collect.ImmutableList;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -54,7 +55,8 @@ public class LimitInterceptor {
key = limitPointAnnotation.key();
break;
default:
key = limitPointAnnotation.key() + getIpAddress();
key = limitPointAnnotation.key() + IpUtils
.getIpAddress(((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
}
ImmutableList<String> keys = ImmutableList.of(StringUtils.join(limitPointAnnotation.prefix(), key));
try {
@@ -71,32 +73,8 @@ public class LimitInterceptor {
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException("服务器异常,请稍后再试");
throw new ServiceException(ResultCode.ERROR);
}
}
/**
* 默认unknown常量值
*/
private static final String UNKNOWN = "unknown";
/**
* 获取ip
* @return ip
*/
public String getIpAddress() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}

View File

@@ -4,6 +4,8 @@ import java.lang.annotation.*;
/**
* 演示站点注解
* <p>
* PS 此注解需要用户登录之后才可以使用
*
* @author Bulbasaur
* @since 2021/7/9 1:40 上午

View File

@@ -0,0 +1,25 @@
package cn.lili.common.aop.annotation;
import java.lang.annotation.*;
import java.util.concurrent.TimeUnit;
/**
* 防止重复提交注解
*
* @author liushuai(liushuai711 @ gmail.com)
* @version v4.0
* @Description:
* @since 2022/1/25 09:17
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface PreventDuplicateSubmissions {
/**
* 过期时间
*/
long expire() default 3;
}

View File

@@ -0,0 +1,67 @@
package cn.lili.common.aop.interceptor;
/**
* 防重复提交业务
*
* @author Chopper
* @version v1.0
* 2022-01-25 09:20
*/
import cn.lili.cache.Cache;
import cn.lili.common.aop.annotation.PreventDuplicateSubmissions;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Aspect
@Component
@Slf4j
public class PreventDuplicateSubmissionsInterceptor {
@Autowired
private Cache<String> cache;
@Before("@annotation(preventDuplicateSubmissions)")
public void interceptor(PreventDuplicateSubmissions preventDuplicateSubmissions) {
try {
Long count = cache.incr(getParams(), preventDuplicateSubmissions.expire());
//如果超过1或者设置的参数则表示重复提交了
if (count.intValue() >= preventDuplicateSubmissions.expire()) {
throw new ServiceException(ResultCode.LIMIT_ERROR);
}
}
//如果参数为空,则表示用户未登录,直接略过,不做处理
catch (NullPointerException e) {
return;
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
throw new ServiceException(ResultCode.ERROR);
}
}
/**
* 获取表单参数
*
* @return
*/
private String getParams() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//请求地址
return request.getRequestURI() + UserContext.getCurrentUser().getId() + UserContext.getCurrentUser().getUsername();
}
}

View File

@@ -23,7 +23,7 @@ public enum PromotionTypeEnum {
/**
* 有促销库存的活动类型
*/
static PromotionTypeEnum[] haveStockPromotion = new PromotionTypeEnum[]{PINTUAN, SECKILL, KANJIA, POINTS_GOODS};
static final PromotionTypeEnum[] haveStockPromotion = new PromotionTypeEnum[]{PINTUAN, SECKILL, KANJIA, POINTS_GOODS};
private final String description;

View File

@@ -115,8 +115,7 @@ public enum ResultCode {
USER_AUTH_EXPIRED(20004, "用户已退出,请重新登录"),
USER_AUTHORITY_ERROR(20005, "权限不足"),
USER_CONNECT_LOGIN_ERROR(20006, "未找到登录信息"),
USER_NAME_EXIST(20007, "该用户名已被注册"),
USER_PHONE_EXIST(20008, "该手机号已被注册"),
USER_EXIST(20008, "该用户名或手机号已被注册"),
USER_PHONE_NOT_EXIST(20009, "手机号不存在"),
USER_PASSWORD_ERROR(20010, "密码不正确"),
USER_NOT_PHONE(20011, "非当前用户的手机号"),

View File

@@ -132,4 +132,18 @@ public class GlobalControllerExceptionHandler {
return ResultUtil.error(ResultCode.PARAMS_ERROR);
}
/**
* bean校验未通过异常
*
* @see javax.validation.Valid
* @see org.springframework.validation.Validator
* @see org.springframework.validation.DataBinder
*/
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ResultMessage<Object> constraintViolationExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) {
ConstraintViolationException exception = (ConstraintViolationException) e;
return ResultUtil.error(ResultCode.PARAMS_ERROR.code(), exception.getMessage());
}
}

View File

@@ -25,6 +25,11 @@ public class AuthUser implements Serializable {
*/
private String nickName;
/**
* 头像
*/
private String face;
/**
* id
*/
@@ -63,16 +68,18 @@ public class AuthUser implements Serializable {
*/
private Boolean isSuper = false;
public AuthUser(String username, String id, String nickName, UserEnums role) {
public AuthUser(String username, String id, String nickName, String face, UserEnums role) {
this.username = username;
this.face = face;
this.id = id;
this.role = role;
this.nickName = nickName;
}
public AuthUser(String username, String id, UserEnums manager, String nickName, Boolean isSuper) {
public AuthUser(String username, String id, String face, UserEnums manager, String nickName, Boolean isSuper) {
this.username = username;
this.id = id;
this.face = face;
this.role = manager;
this.isSuper = isSuper;
this.nickName = nickName;

View File

@@ -37,6 +37,19 @@ public class UserContext {
return null;
}
/**
* 根据request获取用户信息
*
* @return 授权用户
*/
public static String getUuid() {
if (RequestContextHolder.getRequestAttributes() != null) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
return request.getHeader(SecurityEnum.UUID.getValue());
}
return null;
}
/**
* 根据jwt获取token重的用户信息

View File

@@ -10,7 +10,7 @@ public enum SecurityEnum {
/**
* 存在与header中的token参数头 名
*/
HEADER_TOKEN("accessToken"), USER_CONTEXT("userContext"), JWT_SECRET("secret");
HEADER_TOKEN("accessToken"), USER_CONTEXT("userContext"), JWT_SECRET("secret"), UUID("uuid");
String value;

View File

@@ -2,9 +2,11 @@ package cn.lili.common.security.filter;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.http.HtmlUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.owasp.html.Sanitizers;
import org.owasp.html.HtmlPolicyBuilder;
import org.owasp.html.PolicyFactory;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
@@ -17,7 +19,6 @@ import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
/**
@@ -30,28 +31,26 @@ import java.util.Map;
@Slf4j
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
/**
* xss过滤参数
*
* @todo 这里的参数应该更智能些例如iv前端的参数包含这两个字母就会放过这是有问题的
*/
private static final String[] IGNORE_FIELD = {
"logo",
"url",
"photo",
"intro",
"content",
"name",
"image",
"encrypted",
"iv",
"mail",
"sell",
"privateKey",
"wechatpay",
//允许的标签
private static final String[] allowedTags = {"h1", "h2", "h3", "h4", "h5", "h6",
"span", "strong",
"img", "video", "source", "iframe", "code",
"blockquote", "p", "div",
"ul", "ol", "li",
"table", "thead", "caption", "tbody", "tr", "th", "td", "br",
"a"
};
//需要转化的标签
private static final String[] needTransformTags = {"article", "aside", "command", "datalist", "details", "figcaption", "figure",
"footer", "header", "hgroup", "section", "summary"};
//带有超链接的标签
private static final String[] linkTags = {"img", "video", "source", "a", "iframe", "p"};
//带有超链接的标签
private static final String[] allowAttributes = {"style", "src", "href", "target", "width", "height"};
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
@@ -252,9 +251,20 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private String cleanXSS(String value) {
if (value != null) {
value = Sanitizers.FORMATTING.and(Sanitizers.LINKS).sanitize(value);
// 自定义策略
PolicyFactory policy = new HtmlPolicyBuilder()
.allowStandardUrlProtocols()
//所有允许的标签
.allowElements(allowedTags)
//内容标签转化为div
.allowElements((elementName, attributes) -> "div", needTransformTags)
.allowAttributes(allowAttributes).onElements(linkTags)
.allowStyling()
.toFactory();
// basic prepackaged policies for links, tables, integers, images, styles, blocks
value = policy.sanitize(value);
}
return value;
return HtmlUtil.unescape(value);
}
/**
@@ -265,12 +275,7 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
* @return 参数值
*/
private String filterXss(String name, String value) {
if (CharSequenceUtil.containsAny(name.toLowerCase(Locale.ROOT), IGNORE_FIELD)) {
// 忽略的处理,(过滤敏感字符)
return value;
} else {
return cleanXSS(value);
}
return cleanXSS(value);
}
}

View File

@@ -72,7 +72,7 @@ public class SensitiveJsonSerializer extends JsonSerializer<String>
AuthUser authUser = UserContext.getCurrentUser();
//默认脱敏
if (authUser == null) {
return true;
return false;
}
//如果是店铺

View File

@@ -11,16 +11,16 @@ import cn.lili.common.security.token.Token;
* @version v1.0
* 2020-11-13 10:13
*/
public abstract class AbstractTokenGenerate {
public abstract class AbstractTokenGenerate<T> {
/**
* 生成token
*
* @param username 用户名
* @param user 用户名
* @param longTerm 是否长时间有效
* @return TOKEN对象
*/
public abstract Token createToken(String username, Boolean longTerm);
public abstract Token createToken(T user, Boolean longTerm);
/**
* 刷新token

View File

@@ -2,6 +2,7 @@ package cn.lili.common.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
/**
* 金额计算工具
@@ -24,27 +25,29 @@ public final class CurrencyUtil {
/**
* 提供精确的加法运算。
*
* @param v1 被加数
* @param v2 加数
* @return 两个参数的和
* @return 累加之和
*/
public static Double add(double v1, double v2) {
BigDecimal b1 = BigDecimal.valueOf(v1);
BigDecimal b2 = BigDecimal.valueOf(v2);
return b1.add(b2).setScale(2, RoundingMode.HALF_UP).doubleValue();
public static Double add(double... params) {
BigDecimal result = new BigDecimal("0");
for (double param : params) {
BigDecimal bigParam = BigDecimal.valueOf(param);
result = result.add(bigParam).setScale(2, RoundingMode.HALF_UP);
}
return result.doubleValue();
}
/**
* 提供精确的减法运算。
*
* @param v1 被减数
* @param v2 减数
* @return 两个参数的差
* @return 第一个参数为被减数,其余数字为减数
*/
public static double sub(double v1, double v2) {
BigDecimal b1 = BigDecimal.valueOf(v1);
BigDecimal b2 = BigDecimal.valueOf(v2);
return b1.subtract(b2).setScale(2, RoundingMode.HALF_UP).doubleValue();
public static Double sub(double... params) {
BigDecimal result = BigDecimal.valueOf(params[0]);
params = Arrays.stream(params).skip(1).toArray();
for (double param : params) {
BigDecimal bigParam = BigDecimal.valueOf(param);
result = result.subtract(bigParam).setScale(2, RoundingMode.HALF_UP);
}
return result.doubleValue();
}
/**

View File

@@ -2,6 +2,7 @@ package cn.lili.common.utils;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
@@ -10,18 +11,29 @@ import java.util.Date;
*
* @author Chopper
*/
@Slf4j
public class SnowFlake {
/**
* 机器id
*/
private static long workerId = 0L;
/**
* 机房id
*/
private static long datacenterId = 0L;
// /**
// * 机器id
// */
// private static long workerId = 0L;
// /**
// * 机房id
// */
// public static long datacenterId = 0L;
private static Snowflake snowflake = IdUtil.createSnowflake(workerId, datacenterId);
private static Snowflake snowflake;
/**
* 初始化配置
*
* @param workerId
* @param datacenterId
*/
public static void initialize(long workerId, long datacenterId) {
snowflake = IdUtil.getSnowflake(workerId, datacenterId);
}
public static long getId() {
return snowflake.nextId();
@@ -29,12 +41,14 @@ public class SnowFlake {
/**
* 生成字符,带有前缀
*
* @param prefix
* @return
*/
public static String createStr(String prefix) {
return prefix + DateUtil.toString(new Date(), "yyyyMMdd") + SnowFlake.getId();
}
public static String getIdStr() {
return snowflake.nextId() + "";
}

View File

@@ -0,0 +1,58 @@
package cn.lili.common.utils;
import cn.lili.cache.Cache;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;
/**
* SnowflakeInitiator
*
* @author Chopper
* @version v1.0
* 2022-01-14 14:04
*/
@Component
@Slf4j
public class SnowflakeInitiator {
/**
* 缓存前缀
*/
private static String KEY = "{Snowflake}";
@Autowired
private Cache cache;
/**
* 尝试初始化
*
* @return
*/
@PostConstruct
public void init() {
Long num = cache.incr(KEY);
long dataCenter = num / 32;
long workedId = num % 32;
//如果数据中心大于32则抹除缓存从头开始
if (dataCenter >= 32) {
cache.remove(KEY);
num = cache.incr(KEY);
dataCenter = num / 32;
workedId = num % 32;
}
SnowFlake.initialize(workedId, dataCenter);
}
public static void main(String[] args) {
SnowFlake.initialize(0, 8);
System.out.println(SnowFlake.getId());
}
}

View File

@@ -31,8 +31,7 @@ public class SearchVO implements Serializable {
if (StringUtils.isEmpty(startDate)) {
return null;
}
Date date = DateUtil.toDate(startDate, DateUtil.STANDARD_DATE_FORMAT);
return date;
return DateUtil.toDate(startDate, DateUtil.STANDARD_DATE_FORMAT);
}
public Date getConvertEndDate() {

View File

@@ -331,6 +331,9 @@ public abstract class BaseElasticsearchService {
" }\n" +
" }\n" +
" },\n" +
" \"promotionMapJson\": {\n" +
" \"type\": \"text\"\n" +
" },\n" +
" \"thumbnail\": {\n" +
" \"type\": \"text\",\n" +
" \"fields\": {\n" +

View File

@@ -63,7 +63,7 @@ public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
restBuilder.setRequestConfigCallback(requestConfigBuilder ->
requestConfigBuilder.setConnectTimeout(1000) //time until a connection with the server is established.
.setSocketTimeout(12 * 1000) //time of inactivity to wait for packets[data] to receive.
.setConnectionRequestTimeout(2 * 1000)); //time to fetch a connection from the connection pool 0 for infinite.
.setConnectionRequestTimeout(-1)); //time to fetch a connection from the connection pool 0 for infinite.
client = new RestHighLevelClient(restBuilder);
return client;

View File

@@ -87,7 +87,7 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
this.remove(queryWrapper);
throw new NoPermissionException("未绑定用户");
}
return memberTokenGenerate.createToken(member.getUsername(), longTerm);
return memberTokenGenerate.createToken(member, longTerm);
} catch (NoPermissionException e) {
throw e;
}
@@ -222,7 +222,7 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
//如果不存在会员则进行绑定微信openid 和 unionid并且登录
if (member != null) {
bindMpMember(openId, unionId, member);
return memberTokenGenerate.createToken(member.getUsername(), true);
return memberTokenGenerate.createToken(member, true);
}
//如果没有会员,则根据手机号注册会员
@@ -230,7 +230,7 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
memberService.save(newMember);
newMember = memberService.findByUsername(newMember.getUsername());
bindMpMember(openId, unionId, newMember);
return memberTokenGenerate.createToken(newMember.getUsername(), true);
return memberTokenGenerate.createToken(newMember, true);
}
@Override

View File

@@ -2,13 +2,14 @@ package cn.lili.modules.distribution.entity.dto;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Objects;
/**
* 分销员商品查询条件
*
@@ -37,13 +38,13 @@ public class DistributionGoodsSearchParams extends PageVO {
public <T> QueryWrapper<T> storeQueryWrapper() {
QueryWrapper<T> queryWrapper = this.distributionQueryWrapper();
queryWrapper.eq("dg.store_id", UserContext.getCurrentUser().getStoreId());
queryWrapper.eq("dg.store_id", Objects.requireNonNull(UserContext.getCurrentUser()).getStoreId());
return queryWrapper;
}
public <T> QueryWrapper<T> distributionQueryWrapper() {
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
queryWrapper.like(StringUtils.isNotEmpty(goodsName), "dg.goods_name", goodsName);
queryWrapper.like(CharSequenceUtil.isNotEmpty(goodsName), "dg.goods_name", goodsName);
return queryWrapper;
}

View File

@@ -13,21 +13,21 @@ public interface DistributionSelectedGoodsService extends IService<DistributionS
/**
* 分销员添加分销商品
* @param distributionGoodsId 分销商品ID
* @return
* @return 是否添加成功
*/
boolean add(String distributionGoodsId);
/**
* 分销员添加分销商品
* 分销员删除分销商品
* @param distributionGoodsId 分销商品ID
* @return
* @return 是否删除成功
*/
boolean delete(String distributionGoodsId);
/**
* 分销员添加分销商品
* 分销员删除分销商品(管理员操作)
* @param distributionGoodsId 分销商品ID
* @return
* @return 是否删除成功
*/
boolean deleteByDistributionGoodsId(String distributionGoodsId);
}

View File

@@ -40,7 +40,6 @@ import java.util.Date;
* @since 2020-03-126 18:04:56
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class DistributionCashServiceImpl extends ServiceImpl<DistributionCashMapper, DistributionCash> implements DistributionCashService {
/**
* 分销员

View File

@@ -34,7 +34,6 @@ import java.util.Objects;
* @since 2020-03-24 23:04:56
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class DistributionGoodsServiceImpl extends ServiceImpl<DistributionGoodsMapper, DistributionGoods> implements DistributionGoodsService {
/**

View File

@@ -42,7 +42,6 @@ import java.util.List;
*/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class DistributionOrderServiceImpl extends ServiceImpl<DistributionOrderMapper, DistributionOrder> implements DistributionOrderService {
/**

View File

@@ -17,7 +17,6 @@ import org.springframework.transaction.annotation.Transactional;
* @since 2020-03-24 23:04:56
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class DistributionSelectedGoodsServiceImpl extends ServiceImpl<DistributionSelectedGoodsMapper, DistributionSelectedGoods> implements DistributionSelectedGoodsService {
/**
@@ -47,12 +46,6 @@ public class DistributionSelectedGoodsServiceImpl extends ServiceImpl<Distributi
.eq(DistributionSelectedGoods::getDistributionId, distributionId));
}
/**
* 分销员添加分销商品
*
* @param distributionGoodsId 商品ID
* @return
*/
@Override
public boolean deleteByDistributionGoodsId(String distributionGoodsId) {
return this.remove(new LambdaQueryWrapper<DistributionSelectedGoods>()

View File

@@ -38,7 +38,6 @@ import java.util.concurrent.TimeUnit;
* @since 2020-03-14 23:04:56
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class DistributionServiceImpl extends ServiceImpl<DistributionMapper, Distribution> implements DistributionService {
/**

View File

@@ -29,7 +29,6 @@ import java.util.List;
* @since 2020/11/26 17:50
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class FileServiceImpl extends ServiceImpl<FileMapper, File> implements FileService {
@Autowired

View File

@@ -103,7 +103,7 @@ public class GoodsOperationDTO implements Serializable {
* @see cn.lili.modules.goods.entity.enums.GoodsTypeEnum
*/
@ApiModelProperty(value = "商品类型")
@EnumValue(strValues = {"PHYSICAL_GOODS","VIRTUAL_GOODS","E_COUPON"},message = "商品类型参数值错误")
@EnumValue(strValues = {"PHYSICAL_GOODS", "VIRTUAL_GOODS", "E_COUPON"}, message = "商品类型参数值错误")
private String goodsType;
/**
@@ -112,6 +112,9 @@ public class GoodsOperationDTO implements Serializable {
@ApiModelProperty(value = "商品视频")
private String goodsVideo;
public String getGoodsName() {
//对商品对名称做一个极限处理。这里没有用xss过滤是因为xss过滤为全局过滤影响很大。
// 业务中,全局代码中只有商品名称不能拥有英文逗号,是由于商品名称存在一个数据库联合查询,结果要根据逗号分组
return goodsName.replace(",", "");
}
}

View File

@@ -131,9 +131,9 @@ public class GoodsSearchParams extends PageVO {
if (CharSequenceUtil.isNotEmpty(price)) {
String[] s = price.split("_");
if (s.length > 1) {
queryWrapper.ge("price", s[1]);
queryWrapper.between("price", s[0], s[1]);
} else {
queryWrapper.le("price", s[0]);
queryWrapper.ge("price", s[0]);
}
}
}

View File

@@ -0,0 +1,19 @@
package cn.lili.modules.goods.event;
import lombok.Data;
import org.springframework.context.ApplicationEvent;
/**
* @author paulG
* @since 2022/1/19
**/
@Data
public class GeneratorEsGoodsIndexEvent extends ApplicationEvent {
private String goodsId;
public GeneratorEsGoodsIndexEvent(Object source, String goodsId) {
super(source);
this.goodsId = goodsId;
}
}

View File

@@ -0,0 +1,38 @@
package cn.lili.modules.goods.listener;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.modules.goods.event.GeneratorEsGoodsIndexEvent;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.GoodsTagsEnum;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
/**
* @author paulG
* @since 2022/1/19
**/
@Component
public class GeneratorEsGoodsIndexListener {
/**
* rocketMq
*/
@Autowired
private RocketMQTemplate rocketMQTemplate;
/**
* rocketMq配置
*/
@Autowired
private RocketmqCustomProperties rocketmqCustomProperties;
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void generatorEsGoodsIndex(GeneratorEsGoodsIndexEvent esGoodsIndexEvent) {
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.GENERATOR_GOODS_INDEX.name();
//发送mq消息
rocketMQTemplate.asyncSend(destination, esGoodsIndexEvent.getGoodsId(), RocketmqSendCallbackBuilder.commonCallback());
}
}

View File

@@ -4,7 +4,11 @@ package cn.lili.modules.goods.service;
import cn.lili.modules.goods.entity.dos.Category;
import cn.lili.modules.goods.entity.vos.CategoryVO;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import java.io.Serializable;
import java.util.List;
/**
@@ -13,6 +17,7 @@ import java.util.List;
* @author pikachu
* @since 2020-03-02 16:44:56
*/
@CacheConfig(cacheNames = "{category}")
public interface CategoryService extends IService<Category> {
@@ -25,6 +30,15 @@ public interface CategoryService extends IService<Category> {
*/
List<Category> dbList(String parentId);
/**
* 获取分类
*
* @param id
* @return
*/
@Cacheable(key = "#id")
Category getCategoryById(String id);
/**
* 根据分类id集合获取所有分类根据层级排序
*
@@ -86,6 +100,7 @@ public interface CategoryService extends IService<Category> {
* @param category 商品分类信息
* @return 修改结果
*/
@CacheEvict(key = "#category.id")
void updateCategory(Category category);
/**

View File

@@ -195,14 +195,6 @@ public interface GoodsSkuService extends IService<GoodsSku> {
*/
void updateGoodsSkuCommentNum(String skuId);
/**
* 更新商品sku促销价格
*
* @param skuId skuId
* @param promotionPrice 促销价格
*/
void updateGoodsSkuPromotion(String skuId, Double promotionPrice);
/**
* 根据商品id获取全部skuId的集合
*

View File

@@ -34,7 +34,6 @@ import java.util.stream.Collectors;
* @since 2020-02-18 16:18:56
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand> implements BrandService {
/**

View File

@@ -20,7 +20,6 @@ import java.util.List;
* @since 2020-02-18 16:18:56
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class CategoryBrandServiceImpl extends ServiceImpl<CategoryBrandMapper, CategoryBrand> implements CategoryBrandService {
@Override

View File

@@ -37,7 +37,6 @@ import java.util.stream.Collectors;
* 2020-03-02 16:45:03
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class CategoryParameterGroupServiceImpl extends ServiceImpl<CategoryParameterGroupMapper, CategoryParameterGroup> implements CategoryParameterGroupService {
/**
* 商品参数

View File

@@ -36,7 +36,6 @@ import java.util.stream.Collectors;
* @since 2020-02-23 15:18:56
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {
private static final String DELETE_FLAG_COLUMN = "delete_flag";
@@ -60,6 +59,11 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
return this.list(new LambdaQueryWrapper<Category>().eq(Category::getParentId, parentId));
}
@Override
public Category getCategoryById(String id) {
return this.getById(id);
}
/**
* 根据分类id集合获取所有分类根据层级排序
*

View File

@@ -18,7 +18,6 @@ import java.util.List;
* @since 2020-02-23 15:18:56
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class CategorySpecificationServiceImpl extends ServiceImpl<CategorySpecificationMapper, CategorySpecification> implements CategorySpecificationService {
@Override

View File

@@ -33,7 +33,6 @@ import java.util.*;
* @since 2020/12/19
**/
@Service
@Transactional(rollbackFor = Exception.class)
public class DraftGoodsServiceImpl extends ServiceImpl<DraftGoodsMapper, DraftGoods> implements DraftGoodsService {
/**
* 分类

View File

@@ -27,7 +27,6 @@ import java.util.List;
* 2020-02-23 15:18:56
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class GoodsGalleryServiceImpl extends ServiceImpl<GoodsGalleryMapper, GoodsGallery> implements GoodsGalleryService {
/**
* 设置

View File

@@ -54,10 +54,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.*;
/**
* 商品业务层实现
@@ -66,7 +63,6 @@ import java.util.Objects;
* @since 2020-02-23 15:18:56
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements GoodsService {
@@ -119,7 +115,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
@Override
public List<Goods> getByBrandIds(List<String> brandIds) {
LambdaQueryWrapper<Goods> lambdaQueryWrapper = new LambdaQueryWrapper<Goods>();
LambdaQueryWrapper<Goods> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.in(Goods::getBrandId, brandIds);
return list(lambdaQueryWrapper);
}
@@ -197,6 +193,9 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
if (goodsOperationDTO.getGoodsGalleryList() != null && !goodsOperationDTO.getGoodsGalleryList().isEmpty()) {
this.goodsGalleryService.add(goodsOperationDTO.getGoodsGalleryList(), goods.getId());
}
if (GoodsAuthEnum.TOBEAUDITED.name().equals(goods.getAuthFlag())) {
this.deleteEsGoods(Collections.singletonList(goodsId));
}
cache.remove(CachePrefix.GOODS.getPrefix() + goodsId);
}
@@ -306,11 +305,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
}
if (GoodsStatusEnum.DOWN.equals(goodsStatusEnum)) {
//商品删除消息
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.GOODS_DELETE.name();
//发送mq消息
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(goodsIds), RocketmqSendCallbackBuilder.commonCallback());
this.deleteEsGoods(goodsIds);
}
return result;
}
@@ -340,6 +335,9 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
for (Goods goods : goodsList) {
goodsSkuService.updateGoodsSkuStatus(goods);
}
if (GoodsStatusEnum.DOWN.equals(goodsStatusEnum)) {
this.deleteEsGoods(goodsIds);
}
return result;
}
@@ -361,10 +359,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
goodsSkuService.updateGoodsSkuStatus(goods);
}
//商品删除消息
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.GOODS_DELETE.name();
//发送mq消息
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(goodsIds), RocketmqSendCallbackBuilder.commonCallback());
this.deleteEsGoods(goodsIds);
return true;
}
@@ -388,6 +383,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateStock(String goodsId, Integer quantity) {
LambdaUpdateWrapper<Goods> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.set(Goods::getQuantity, quantity);
@@ -447,6 +443,19 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
.eq(Goods::getMarketEnable, GoodsStatusEnum.UPPER.name()));
}
/**
* 发送删除es索引的信息
*
* @param goodsIds 商品id
*/
private void deleteEsGoods(List<String> goodsIds) {
//商品删除消息
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.GOODS_DELETE.name();
//发送mq消息
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(goodsIds), RocketmqSendCallbackBuilder.commonCallback());
}
/**
* 添加商品默认图片
*
@@ -522,8 +531,8 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
/**
* 判断商品是否存在
*
* @param goodsId
* @return
* @param goodsId 商品id
* @return 商品信息
*/
private Goods checkExist(String goodsId) {
Goods goods = getById(goodsId);
@@ -579,20 +588,6 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
}
}
/**
* 获取UpdateWrapper检查用户越权
*
* @return updateWrapper
*/
private LambdaUpdateWrapper<Goods> getUpdateWrapperByManagerAuthority() {
LambdaUpdateWrapper<Goods> updateWrapper = new LambdaUpdateWrapper<>();
AuthUser authUser = this.checkStoreAuthority();
if (authUser != null) {
updateWrapper.eq(Goods::getStoreId, authUser.getStoreId());
}
return updateWrapper;
}
/**
* 获取QueryWrapper检查用户越权
*

View File

@@ -3,9 +3,7 @@ package cn.lili.modules.goods.serviceimpl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
@@ -24,16 +22,20 @@ import cn.lili.modules.goods.entity.vos.GoodsSkuSpecVO;
import cn.lili.modules.goods.entity.vos.GoodsSkuVO;
import cn.lili.modules.goods.entity.vos.GoodsVO;
import cn.lili.modules.goods.entity.vos.SpecValueVO;
import cn.lili.modules.goods.event.GeneratorEsGoodsIndexEvent;
import cn.lili.modules.goods.mapper.GoodsSkuMapper;
import cn.lili.modules.goods.service.CategoryService;
import cn.lili.modules.goods.service.GoodsGalleryService;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.member.entity.dos.FootPrint;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.entity.dto.EvaluationQueryParams;
import cn.lili.modules.member.entity.enums.EvaluationGradeEnum;
import cn.lili.modules.member.service.MemberEvaluationService;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dto.search.PromotionGoodsSearchParams;
import cn.lili.modules.promotion.entity.enums.CouponGetEnum;
import cn.lili.modules.promotion.service.PromotionGoodsService;
import cn.lili.modules.search.entity.dos.EsGoodsAttribute;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.search.service.EsGoodsIndexService;
@@ -47,6 +49,7 @@ 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.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -60,7 +63,6 @@ import java.util.stream.Collectors;
* @since 2020-02-23 15:18:56
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> implements GoodsSkuService {
/**
@@ -104,6 +106,12 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
@Autowired
private EsGoodsIndexService goodsIndexService;
@Autowired
private PromotionGoodsService promotionGoodsService;
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Override
public void add(List<Map<String, Object>> skuList, Goods goods) {
// 检查是否需要生成索引
@@ -117,10 +125,13 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
}
this.updateStock(newSkuList);
generateEs(goods);
if (!newSkuList.isEmpty()) {
generateEs(goods);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(List<Map<String, Object>> skuList, Goods goods, Boolean regeneratorSkuFlag) {
// 是否存在规格
if (skuList == null || skuList.isEmpty()) {
@@ -134,9 +145,9 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
//删除旧索引
for (GoodsSkuVO goodsSkuVO : goodsListByGoodsId) {
oldSkuIds.add(goodsSkuVO.getId());
goodsIndexService.deleteIndexById(goodsSkuVO.getId());
cache.remove(GoodsSkuService.getCacheKeys(goodsSkuVO.getId()));
}
goodsIndexService.deleteIndexByIds(oldSkuIds);
this.removeByIds(oldSkuIds);
//删除sku相册
goodsGalleryService.removeByIds(oldSkuIds);
@@ -164,7 +175,9 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
this.updateBatchById(newSkuList);
}
this.updateStock(newSkuList);
generateEs(goods);
if (GoodsAuthEnum.PASS.name().equals(goods.getAuthFlag()) && !newSkuList.isEmpty()) {
generateEs(goods);
}
}
/**
@@ -241,11 +254,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
//获取当前商品的索引信息
EsGoodsIndex goodsIndex = goodsIndexService.findById(skuId);
if (goodsIndex == null) {
goodsIndex = goodsIndexService.getTempEsGoodsIndex(goodsSku, goodsVO.getGoodsParamsDTOList());
//发送mq消息
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.RESET_GOODS_INDEX.name();
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(Collections.singletonList(goodsIndex)), RocketmqSendCallbackBuilder.commonCallback());
goodsIndex = goodsIndexService.getResetEsGoodsIndex(goodsSku, goodsVO.getGoodsParamsDTOList());
}
//商品规格
@@ -253,9 +262,6 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
Map<String, Object> promotionMap = goodsIndex.getPromotionMap();
//设置当前商品的促销价格
if (promotionMap != null && !promotionMap.isEmpty() && goodsIndex.getPromotionPrice() != null) {
goodsSkuDetail.setPromotionPrice(goodsIndex.getPromotionPrice());
}
if (promotionMap != null && !promotionMap.isEmpty()) {
promotionMap = promotionMap.entrySet().stream().parallel().filter(i -> {
JSONObject jsonObject = JSONUtil.parseObj(i.getValue());
@@ -265,11 +271,18 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
(jsonObject.get("endTime") == null || jsonObject.get("endTime", Date.class).getTime() >= System.currentTimeMillis());
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
boolean containsPromotion = promotionMap.keySet().stream().anyMatch(i ->
i.contains(PromotionTypeEnum.SECKILL.name()) || i.contains(PromotionTypeEnum.PINTUAN.name()));
if (containsPromotion && goodsIndex.getPromotionPrice() != null) {
goodsSkuDetail.setPromotionFlag(true);
goodsSkuDetail.setPromotionPrice(goodsIndex.getPromotionPrice());
Optional<Map.Entry<String, Object>> containsPromotion = promotionMap.entrySet().stream().filter(i ->
i.getKey().contains(PromotionTypeEnum.SECKILL.name()) || i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst();
if (containsPromotion.isPresent()) {
JSONObject jsonObject = JSONUtil.parseObj(containsPromotion.get().getValue());
PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
searchParams.setSkuId(skuId);
searchParams.setPromotionId(jsonObject.get("id").toString());
PromotionGoods promotionsGoods = promotionGoodsService.getPromotionsGoods(searchParams);
if (promotionsGoods != null && promotionsGoods.getPrice() != null) {
goodsSkuDetail.setPromotionFlag(true);
goodsSkuDetail.setPromotionPrice(promotionsGoods.getPrice());
}
} else {
goodsSkuDetail.setPromotionFlag(false);
goodsSkuDetail.setPromotionPrice(null);
@@ -319,7 +332,9 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
cache.remove(GoodsSkuService.getCacheKeys(sku.getId()));
cache.put(GoodsSkuService.getCacheKeys(sku.getId()), sku);
}
generateEs(goods);
if (!goodsSkus.isEmpty()) {
generateEs(goods);
}
}
}
@@ -487,12 +502,11 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
//获取商品信息
GoodsSku goodsSku = this.getGoodsSkuByIdFromCache(skuId);
LambdaQueryWrapper<MemberEvaluation> goodEvaluationQueryWrapper = new LambdaQueryWrapper<>();
goodEvaluationQueryWrapper.eq(MemberEvaluation::getSkuId, goodsSku.getId());
goodEvaluationQueryWrapper.eq(MemberEvaluation::getGrade, EvaluationGradeEnum.GOOD.name());
EvaluationQueryParams queryParams = new EvaluationQueryParams();
queryParams.setGrade(EvaluationGradeEnum.GOOD.name());
queryParams.setSkuId(goodsSku.getId());
//好评数量
long highPraiseNum = memberEvaluationService.count(goodEvaluationQueryWrapper);
long highPraiseNum = memberEvaluationService.getEvaluationCount(queryParams);
//更新商品评价数量
goodsSku.setCommentNum(goodsSku.getCommentNum() != null ? goodsSku.getCommentNum() + 1 : 1);
@@ -516,22 +530,6 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
goodsService.updateGoodsCommentNum(goodsSku.getGoodsId());
}
/**
* 更新商品sku促销价格
*
* @param skuId skuId
* @param promotionPrice 促销价格
*/
@Override
public void updateGoodsSkuPromotion(String skuId, Double promotionPrice) {
LambdaUpdateWrapper<GoodsSku> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(GoodsSku::getId, skuId);
updateWrapper.set(GoodsSku::getPromotionPrice, promotionPrice);
updateWrapper.set(GoodsSku::getPromotionFlag, true);
this.update(updateWrapper);
cache.remove(GoodsSkuService.getCacheKeys(skuId));
}
/**
* 根据商品id获取全部skuId的集合
*
@@ -554,18 +552,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
if (!GoodsStatusEnum.UPPER.name().equals(goods.getMarketEnable()) || !GoodsAuthEnum.PASS.name().equals(goods.getAuthFlag())) {
return;
}
ThreadUtil.execAsync(() -> {
try {
// 延时执行,防止商品未保存完成就去生成商品索引导致生成索引时找不到商品问题
Thread.sleep(2000);
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.GENERATOR_GOODS_INDEX.name();
//发送mq消息
rocketMQTemplate.asyncSend(destination, goods.getId(), RocketmqSendCallbackBuilder.commonCallback());
} catch (InterruptedException e) {
log.error("发送商品索引信息失败!", e);
Thread.currentThread().interrupt();
}
});
applicationEventPublisher.publishEvent(new GeneratorEsGoodsIndexEvent("生成商品索引事件", goods.getId()));
}
/**
@@ -591,7 +578,8 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
* @param skuList sku列表
* @param goods 商品信息
*/
private List<GoodsSku> addGoodsSku(List<Map<String, Object>> skuList, Goods goods) {
@Transactional(rollbackFor = Exception.class)
List<GoodsSku> addGoodsSku(List<Map<String, Object>> skuList, Goods goods) {
List<GoodsSku> skus = new ArrayList<>();
for (Map<String, Object> skuVO : skuList) {
Map<String, Object> resultMap = this.add(skuVO, goods);
@@ -700,7 +688,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
}
//设置规格商品缩略图
//如果规格没有图片,则用商品图片复盖。有则增加规格图片,放在商品图片集合之前
if (spec.getValue() != null && StrUtil.isNotEmpty(spec.getValue().toString())) {
if (CharSequenceUtil.isNotEmpty(spec.getValue().toString())) {
thumbnail = goodsGalleryService.getGoodsGallery(images.get(0).get("url")).getThumbnail();
small = goodsGalleryService.getGoodsGallery(images.get(0).get("url")).getSmall();
}

View File

@@ -14,6 +14,5 @@ import org.springframework.transaction.annotation.Transactional;
* @since 2020/10/15
**/
@Service
@Transactional(rollbackFor = Exception.class)
public class GoodsWordsServiceImpl extends ServiceImpl<GoodsWordsMapper, GoodsWords> implements GoodsWordsService {
}

View File

@@ -30,7 +30,6 @@ import java.util.List;
* @since 2020-03-07 16:18:56
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class StoreGoodsLabelServiceImpl extends ServiceImpl<StoreGoodsLabelMapper, StoreGoodsLabel> implements StoreGoodsLabelService {
/**

View File

@@ -1,12 +1,11 @@
package cn.lili.modules.member.entity.dto;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.utils.StringUtils;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.vo.PageVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 评价查询条件
@@ -14,13 +13,19 @@ import lombok.Data;
* @author Bulbasaur
* @since 2020/11/30 14:52
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class EvaluationQueryParams extends PageVO {
@ApiModelProperty(value = "ID")
private String id;
@ApiModelProperty(value = "买家ID")
private String memberId;
@ApiModelProperty(value = "skuID")
private String skuId;
@ApiModelProperty(value = "会员名称")
private String memberName;
@@ -51,40 +56,42 @@ public class EvaluationQueryParams extends PageVO {
@ApiModelProperty(value = "状态")
private String status;
public EvaluationQueryParams() {
}
public <T> QueryWrapper<T> queryWrapper() {
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
if (StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime)) {
if (CharSequenceUtil.isNotEmpty(id)) {
queryWrapper.eq("id", id);
}
if (CharSequenceUtil.isNotEmpty(startTime) && CharSequenceUtil.isNotEmpty(endTime)) {
queryWrapper.between("create_time", startTime, endTime);
}
if (StringUtils.isNotEmpty(grade)) {
if (CharSequenceUtil.isNotEmpty(grade)) {
queryWrapper.eq("grade", grade);
}
if (StringUtils.isNotEmpty(goodsName)) {
if (CharSequenceUtil.isNotEmpty(goodsName)) {
queryWrapper.like("goods_name", goodsName);
}
if (StringUtils.isNotEmpty(storeName)) {
if (CharSequenceUtil.isNotEmpty(storeName)) {
queryWrapper.like("store_name", storeName);
}
if (StringUtils.isNotEmpty(memberName)) {
if (CharSequenceUtil.isNotEmpty(memberName)) {
queryWrapper.like("member_name", memberName);
}
if (StringUtils.isNotEmpty(goodsId)) {
if (CharSequenceUtil.isNotEmpty(goodsId)) {
queryWrapper.eq("goods_id", goodsId);
}
if (StringUtils.isNotEmpty(storeId)) {
if (CharSequenceUtil.isNotEmpty(skuId)) {
queryWrapper.eq("sku_id", skuId);
}
if (CharSequenceUtil.isNotEmpty(storeId)) {
queryWrapper.eq("store_id", storeId);
}
if (StringUtils.isNotEmpty(memberId)) {
if (CharSequenceUtil.isNotEmpty(memberId)) {
queryWrapper.eq("member_id", memberId);
}
if (StringUtils.isNotEmpty(haveImage)) {
if (CharSequenceUtil.isNotEmpty(haveImage)) {
queryWrapper.eq("have_image", haveImage);
}
if (StringUtils.isNotEmpty(status)) {
if (CharSequenceUtil.isNotEmpty(status)) {
queryWrapper.eq("status", status);
}
queryWrapper.eq("delete_flag", false);

View File

@@ -34,8 +34,9 @@ public interface FootprintMapper extends BaseMapper<FootPrint> {
*
* @param memberId 会员ID
*/
@Delete("DELETE FROM li_foot_print WHERE (SELECT COUNT(b.id) FROM ( SELECT * FROM li_foot_print WHERE member_id = #{memberId} ) b) >100 " +
" AND id =(SELECT a.id FROM ( SELECT * FROM li_foot_print WHERE member_id = #{memberId} ORDER BY create_time ASC LIMIT 1 ) AS a)")
@Delete("DELETE FROM li_foot_print l1 WHERE l1.id IN (" +
"SELECT l2.id FROM (" +
"SELECT l3.id FROM li_foot_print l3 WHERE l3.member_id=${memberId} ORDER BY id DESC LIMIT 100,100) l2)")
void deleteLastFootPrint(String memberId);
}

View File

@@ -41,9 +41,10 @@ public interface MemberEvaluationService extends IService<MemberEvaluation> {
* 4.发送用户评价消息修改商品的评价数量以及好评率
*
* @param memberEvaluationDTO 评论
* @param isSelf 是否自己操作true买家操作/false 系统操作)
* @return 操作状态
*/
MemberEvaluationDTO addMemberEvaluation(MemberEvaluationDTO memberEvaluationDTO);
MemberEvaluationDTO addMemberEvaluation(MemberEvaluationDTO memberEvaluationDTO, Boolean isSelf);
/**
* 根据ID查询会员评价
@@ -88,5 +89,26 @@ public interface MemberEvaluationService extends IService<MemberEvaluation> {
*/
EvaluationNumberVO getEvaluationNumber(String goodsId);
/**
* 获取今天新增的评价数量
*
* @return 今日评价数量
*/
long todayMemberEvaluation();
/**
* 获取等待回复评价数量
*
* @return 等待回复评价数量
*/
long getWaitReplyNum();
/**
* 统计商品评价数量
*
* @param evaluationQueryParams 查询条件
* @return 商品评价数量
*/
long getEvaluationCount(EvaluationQueryParams evaluationQueryParams);
}

View File

@@ -33,7 +33,7 @@ public interface MemberService extends IService<Member> {
Member getUserInfo();
/**
* 是否可以通过手机获取用户
* 通过手机获取用户
*
* @param mobile 手机号
* @return 操作状态
@@ -222,6 +222,7 @@ public interface MemberService extends IService<Member> {
void logout(UserEnums userEnums);
/**
* <<<<<<< HEAD
* 修改会员是否拥有店铺
*
* @param haveStore 是否拥有店铺
@@ -237,4 +238,19 @@ public interface MemberService extends IService<Member> {
* @param ids 会员id
*/
void resetPassword(List<String> ids);
/*
* 获取所有会员的手机号
*
* @return 所有会员的手机号
*/
List<String> getAllMemberMobile();
/**
* 更新会员登录时间为最新时间
*
* @param memberId 会员id
* @return 是否更新成功
*/
boolean updateMemberLoginTime(String memberId);
}

View File

@@ -27,7 +27,6 @@ import java.util.Objects;
* @since 2020/11/18 10:46 上午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class FootprintServiceImpl extends ServiceImpl<FootprintMapper, FootPrint> implements FootprintService {
/**

View File

@@ -26,7 +26,6 @@ import java.util.Optional;
* @since 2020/11/18 2:25 下午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class GoodsCollectionServiceImpl extends ServiceImpl<GoodsCollectionMapper, GoodsCollection> implements GoodsCollectionService {

View File

@@ -23,7 +23,6 @@ import java.util.Objects;
* @since 2020/11/18 9:44 上午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class MemberAddressServiceImpl extends ServiceImpl<MemberAddressMapper, MemberAddress> implements MemberAddressService {
@Override

View File

@@ -1,11 +1,15 @@
package cn.lili.modules.member.serviceimpl;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.SwitchEnum;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.sensitive.SensitiveWordsFilter;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.goods.entity.dos.GoodsSku;
@@ -29,6 +33,7 @@ import cn.lili.modules.order.order.service.OrderService;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.GoodsTagsEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -51,7 +56,6 @@ import java.util.Map;
* @since 2020-02-25 14:10:16
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class MemberEvaluationServiceImpl extends ServiceImpl<MemberEvaluationMapper, MemberEvaluation> implements MemberEvaluationService {
/**
@@ -102,13 +106,15 @@ public class MemberEvaluationServiceImpl extends ServiceImpl<MemberEvaluationMap
}
@Override
public MemberEvaluationDTO addMemberEvaluation(MemberEvaluationDTO memberEvaluationDTO) {
public MemberEvaluationDTO addMemberEvaluation(MemberEvaluationDTO memberEvaluationDTO, Boolean isSelf) {
//获取子订单信息
OrderItem orderItem = orderItemService.getBySn(memberEvaluationDTO.getOrderItemSn());
//获取订单信息
Order order = orderService.getBySn(orderItem.getOrderSn());
//检测是否可以添加会员评价
checkMemberEvaluation(orderItem, order);
if (isSelf) {
checkMemberEvaluation(orderItem, order);
}
//获取用户信息
Member member = memberService.getUserInfo();
//获取商品信息
@@ -191,6 +197,31 @@ public class MemberEvaluationServiceImpl extends ServiceImpl<MemberEvaluationMap
return evaluationNumberVO;
}
@Override
public long todayMemberEvaluation() {
return this.count(new LambdaQueryWrapper<MemberEvaluation>().ge(MemberEvaluation::getCreateTime, DateUtil.beginOfDay(new DateTime())));
}
@Override
public long getWaitReplyNum() {
QueryWrapper<MemberEvaluation> queryWrapper = Wrappers.query();
queryWrapper.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()),
"store_id", UserContext.getCurrentUser().getStoreId());
queryWrapper.eq("reply_status", false);
return this.count(queryWrapper);
}
/**
* 统计商品评价数量
*
* @param evaluationQueryParams 查询条件
* @return 商品评价数量
*/
@Override
public long getEvaluationCount(EvaluationQueryParams evaluationQueryParams) {
return this.count(evaluationQueryParams.queryWrapper());
}
/**
* 检测会员评价
*

View File

@@ -1,27 +1,22 @@
package cn.lili.modules.member.serviceimpl;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.enums.PointTypeEnum;
import cn.lili.modules.member.mapper.MemberMapper;
import cn.lili.modules.member.service.MemberService;
import cn.lili.mybatis.util.PageUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.MemberPointsHistory;
import cn.lili.modules.member.entity.vo.MemberPointsHistoryVO;
import cn.lili.modules.member.mapper.MemberPointsHistoryMapper;
import cn.lili.modules.member.service.MemberPointsHistoryService;
import cn.lili.modules.member.service.MemberService;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* 会员积分历史业务层实现
*
@@ -51,8 +46,8 @@ public class MemberPointsHistoryServiceImpl extends ServiceImpl<MemberPointsHist
@Override
public IPage<MemberPointsHistory> MemberPointsHistoryList(PageVO page, String memberId, String memberName) {
LambdaQueryWrapper<MemberPointsHistory> lambdaQueryWrapper = new LambdaQueryWrapper<MemberPointsHistory>()
.eq(memberId != null, MemberPointsHistory::getMemberId, memberId)
.like(memberName != null, MemberPointsHistory::getMemberName, memberName);
.eq(CharSequenceUtil.isNotEmpty(memberId), MemberPointsHistory::getMemberId, memberId)
.like(CharSequenceUtil.isNotEmpty(memberName), MemberPointsHistory::getMemberName, memberName);
//如果排序为空,则默认创建时间倒序
if (StringUtils.isEmpty(page.getSort())) {
page.setSort("createTime");

View File

@@ -18,6 +18,7 @@ import cn.lili.common.sensitive.SensitiveWordsFilter;
import cn.lili.common.utils.BeanUtil;
import cn.lili.common.utils.CookieUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.utils.UuidUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.connect.config.ConnectAuthEnum;
@@ -50,8 +51,8 @@ import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -63,7 +64,6 @@ import java.util.Objects;
* @since 2021-03-29 14:10:16
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {
/**
@@ -126,6 +126,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
return this.baseMapper.selectOne(queryWrapper);
}
@Override
public Token usernameLogin(String username, String password) {
Member member = this.findMember(username);
@@ -138,7 +139,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
throw new ServiceException(ResultCode.USER_PASSWORD_ERROR);
}
loginBindUser(member);
return memberTokenGenerate.createToken(member.getUsername(), false);
return memberTokenGenerate.createToken(member, false);
}
@Override
@@ -163,7 +164,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
throw new ServiceException(ResultCode.USER_NOT_EXIST);
}
return storeTokenGenerate.createToken(member.getUsername(), false);
return storeTokenGenerate.createToken(member, false);
}
/**
@@ -191,12 +192,10 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
String username = UuidUtils.getUUID();
Member member = new Member(username, UuidUtils.getUUID(), authUser.getAvatar(), authUser.getNickname(),
authUser.getGender() != null ? Convert.toInt(authUser.getGender().getCode()) : 0);
//保存会员
this.save(member);
Member loadMember = this.findByUsername(username);
registerHandler(member);
//绑定登录方式
loginBindUser(loadMember, authUser.getUuid(), authUser.getSource());
return memberTokenGenerate.createToken(username, false);
loginBindUser(member, authUser.getUuid(), authUser.getSource());
return memberTokenGenerate.createToken(member, false);
} catch (ServiceException e) {
log.error("自动注册服务泡出异常:", e);
throw e;
@@ -230,13 +229,23 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
//如果手机号不存在则自动注册用户
if (member == null) {
member = new Member(mobilePhone, UuidUtils.getUUID(), mobilePhone);
//保存会员
this.save(member);
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_REGISTER.name();
rocketMQTemplate.asyncSend(destination, member, RocketmqSendCallbackBuilder.commonCallback());
registerHandler(member);
}
loginBindUser(member);
return memberTokenGenerate.createToken(member.getUsername(), false);
return memberTokenGenerate.createToken(member, false);
}
/**
* 注册方法抽象
*
* @param member
*/
private void registerHandler(Member member) {
member.setId(SnowFlake.getIdStr());
//保存会员
this.save(member);
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_REGISTER.name();
rocketMQTemplate.asyncSend(destination, member, RocketmqSendCallbackBuilder.commonCallback());
}
@Override
@@ -272,13 +281,9 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
//设置会员信息
Member member = new Member(userName, new BCryptPasswordEncoder().encode(password), mobilePhone);
//注册成功后用户自动登录
if (this.save(member)) {
Token token = memberTokenGenerate.createToken(member.getUsername(), false);
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_REGISTER.name();
rocketMQTemplate.asyncSend(destination, member, RocketmqSendCallbackBuilder.commonCallback());
return token;
}
return null;
registerHandler(member);
Token token = memberTokenGenerate.createToken(member, false);
return token;
}
@Override
@@ -306,6 +311,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
LambdaUpdateWrapper<Member> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.eq(Member::getMobile, phone);
lambdaUpdateWrapper.set(Member::getPassword, new BCryptPasswordEncoder().encode(password));
cache.remove(CachePrefix.FIND_MOBILE + uuid);
return this.update(lambdaUpdateWrapper);
} else {
throw new ServiceException(ResultCode.USER_PHONE_NOT_EXIST);
@@ -321,9 +327,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
//添加会员
Member member = new Member(memberAddDTO.getUsername(), new BCryptPasswordEncoder().encode(memberAddDTO.getPassword()), memberAddDTO.getMobile());
this.save(member);
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_REGISTER.name();
rocketMQTemplate.asyncSend(destination, member, RocketmqSendCallbackBuilder.commonCallback());
registerHandler(member);
return member;
}
@@ -420,10 +424,11 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
* @param mobilePhone 手机号
* @return 会员
*/
private Member findByPhone(String mobilePhone) {
private Long findMember(String mobilePhone, String userName) {
QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("mobile", mobilePhone);
return this.baseMapper.selectOne(queryWrapper);
queryWrapper.eq("mobile", mobilePhone)
.or().eq("username", userName);
return this.baseMapper.selectCount(queryWrapper);
}
/**
@@ -597,6 +602,30 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
this.update(lambdaUpdateWrapper);
}
/**
* 获取所有会员的手机号
*
* @return 所有会员的手机号
*/
@Override
public List<String> getAllMemberMobile() {
return this.baseMapper.getAllMemberMobile();
}
/**
* 更新会员登录时间为最新时间
*
* @param memberId 会员id
* @return 是否更新成功
*/
@Override
public boolean updateMemberLoginTime(String memberId) {
LambdaUpdateWrapper<Member> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Member::getId, memberId);
updateWrapper.set(Member::getLastLoginDate, new Date());
return this.update(updateWrapper);
}
/**
* 检测会员
*
@@ -604,13 +633,9 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
* @param mobilePhone 手机号
*/
private void checkMember(String userName, String mobilePhone) {
//判断用户名是否存在
if (findByUsername(userName) != null) {
throw new ServiceException(ResultCode.USER_NAME_EXIST);
}
//判断手机号是否存在
if (findByPhone(mobilePhone) != null) {
throw new ServiceException(ResultCode.USER_PHONE_EXIST);
if (findMember(userName, mobilePhone) > 0) {
throw new ServiceException(ResultCode.USER_EXIST);
}
}

View File

@@ -67,14 +67,6 @@ public class MemberSignServiceImpl extends ServiceImpl<MemberSignMapper, MemberS
//获取当前会员信息
AuthUser authUser = UserContext.getCurrentUser();
if (authUser != null) {
QueryWrapper<MemberSign> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("member_id", authUser.getId());
queryWrapper.between("create_time", new Date(DateUtil.startOfTodDay() * 1000), DateUtil.getCurrentDayEndTime());
//校验今天是否已经签到
List<MemberSign> todaySigns = this.baseMapper.getTodayMemberSign(queryWrapper);
if (todaySigns.size() > 0) {
throw new ServiceException(ResultCode.MEMBER_SIGN_REPEAT);
}
//当前签到天数的前一天日期
List<MemberSign> signs = this.baseMapper.getBeforeMemberSign(authUser.getId());
//构建参数
@@ -89,14 +81,17 @@ public class MemberSignServiceImpl extends ServiceImpl<MemberSignMapper, MemberS
} else {
memberSign.setSignDay(1);
}
Integer result = this.baseMapper.insert(memberSign);
//签到成功后发送消息赠送积分
if (result > 0) {
//手动写入创建时间,以保证唯一索引生效
memberSign.setCreateTime(DateUtil.getCurrentDayEndTime());
try {
this.baseMapper.insert(memberSign);
//签到成功后发送消息赠送积分
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_SING.name();
rocketMQTemplate.asyncSend(destination, memberSign, RocketmqSendCallbackBuilder.commonCallback());
return true;
} catch (Exception e) {
throw new ServiceException(ResultCode.MEMBER_SIGN_REPEAT);
}
return false;
}
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
}

View File

@@ -1,14 +1,17 @@
package cn.lili.modules.member.token;
import cn.lili.common.context.ThreadContextHolder;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.security.token.Token;
import cn.lili.common.security.token.TokenUtil;
import cn.lili.common.security.token.base.AbstractTokenGenerate;
import cn.lili.common.context.ThreadContextHolder;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.service.MemberService;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.MemberTagsEnum;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -22,17 +25,17 @@ import java.util.Date;
* @since 2020/11/16 10:50
*/
@Component
public class MemberTokenGenerate extends AbstractTokenGenerate {
@Autowired
private MemberService memberService;
public class MemberTokenGenerate extends AbstractTokenGenerate<Member> {
@Autowired
private TokenUtil tokenUtil;
@Autowired
private RocketmqCustomProperties rocketmqCustomProperties;
@Autowired
private RocketMQTemplate rocketMQTemplate;
@Override
public Token createToken(String username, Boolean longTerm) {
Member member = memberService.findByUsername(username);
public Token createToken(Member member, Boolean longTerm) {
//获取客户端类型
String clientType = ThreadContextHolder.getHttpRequest().getHeader("clientType");
@@ -50,11 +53,12 @@ public class MemberTokenGenerate extends AbstractTokenGenerate {
//记录最后登录时间,客户端类型
member.setLastLoginDate(new Date());
member.setClientEnum(clientTypeEnum.name());
memberService.updateById(member);
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_LOGIN.name();
rocketMQTemplate.asyncSend(destination, member, RocketmqSendCallbackBuilder.commonCallback());
AuthUser authUser = new AuthUser(member.getUsername(), member.getId(),member.getNickName(), UserEnums.MEMBER);
AuthUser authUser = new AuthUser(member.getUsername(), member.getId(), member.getNickName(), member.getFace(), UserEnums.MEMBER);
//登陆成功生成token
return tokenUtil.createToken(username, authUser, longTerm, UserEnums.MEMBER);
return tokenUtil.createToken(member.getUsername(), authUser, longTerm, UserEnums.MEMBER);
}
@Override

View File

@@ -15,12 +15,9 @@ import cn.lili.modules.member.entity.dos.Clerk;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.vo.StoreUserMenuVO;
import cn.lili.modules.member.service.ClerkService;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.member.service.StoreMenuRoleService;
import cn.lili.modules.permission.entity.vo.UserMenuVO;
import cn.lili.modules.store.entity.dos.Store;
import cn.lili.modules.store.service.StoreService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -37,9 +34,7 @@ import java.util.Map;
* @since 2020/11/16 10:51
*/
@Component
public class StoreTokenGenerate extends AbstractTokenGenerate {
@Autowired
private MemberService memberService;
public class StoreTokenGenerate extends AbstractTokenGenerate<Member> {
@Autowired
private StoreService storeService;
@Autowired
@@ -52,10 +47,8 @@ public class StoreTokenGenerate extends AbstractTokenGenerate {
private ClerkService clerkService;
@Override
public Token createToken(String username, Boolean longTerm) {
//生成token
Member member = memberService.findByUsername(username);
if (!member.getHaveStore()) {
public Token createToken(Member member, Boolean longTerm) {
if (Boolean.FALSE.equals(member.getHaveStore())) {
throw new ServiceException(ResultCode.STORE_NOT_OPEN);
}
//根据会员id查询店员信息
@@ -77,9 +70,10 @@ public class StoreTokenGenerate extends AbstractTokenGenerate {
if (store == null) {
throw new ServiceException(ResultCode.STORE_NOT_OPEN);
}
user.setStoreId(store.getId());
user.setStoreName(store.getStoreName());
return tokenUtil.createToken(username, user, longTerm, UserEnums.STORE);
AuthUser authUser = new AuthUser(member.getUsername(), member.getId(), member.getNickName(), store.getStoreLogo(), UserEnums.STORE);
authUser.setStoreId(store.getId());
authUser.setStoreName(store.getStoreName());
return tokenUtil.createToken(member.getUsername(), authUser, longTerm, UserEnums.STORE);
}
@Override

View File

@@ -23,7 +23,6 @@ import org.springframework.transaction.annotation.Transactional;
* @since 2020/11/17 3:48 下午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements MessageService {
@Autowired

View File

@@ -16,7 +16,6 @@ import java.util.List;
* @author Chopper
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class ShortLinkServiceImpl extends ServiceImpl<ShortLinkMapper, ShortLink> implements ShortLinkService {
@Override

View File

@@ -1,7 +1,7 @@
package cn.lili.modules.order.aftersale.entity.dto;
import cn.lili.modules.promotion.entity.dto.BasePromotions;
import cn.lili.modules.promotion.entity.dos.BasePromotions;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

View File

@@ -1,12 +1,13 @@
package cn.lili.modules.order.aftersale.entity.vo;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@@ -17,6 +18,7 @@ import java.util.Date;
* @author paulG
* @since 2020/12/4
**/
@EqualsAndHashCode(callSuper = true)
@Data
public class AfterSaleSearchParams extends PageVO {
@@ -44,6 +46,9 @@ public class AfterSaleSearchParams extends PageVO {
@ApiModelProperty(value = "实际退款金额,可以为范围如10_1000")
private String actualRefundPrice;
@ApiModelProperty(value = "总价格,可以为范围如10_1000")
private String flowPrice;
/**
* @see cn.lili.modules.order.trade.entity.enums.AfterSaleTypeEnum
*/
@@ -66,33 +71,33 @@ public class AfterSaleSearchParams extends PageVO {
public <T> QueryWrapper<T> queryWrapper() {
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
if (StringUtils.isNotEmpty(sn)) {
if (CharSequenceUtil.isNotEmpty(sn)) {
queryWrapper.like("sn", sn);
}
if (StringUtils.isNotEmpty(orderSn)) {
if (CharSequenceUtil.isNotEmpty(orderSn)) {
queryWrapper.like("order_sn", orderSn);
}
//按买家查询
if (StringUtils.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.MEMBER.name())) {
if (CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.MEMBER.name())) {
queryWrapper.eq("member_id", UserContext.getCurrentUser().getId());
}
//按卖家查询
if (StringUtils.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name())) {
if (CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name())) {
queryWrapper.eq("store_id", UserContext.getCurrentUser().getStoreId());
}
if (StringUtils.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.MANAGER.name())
&& StringUtils.isNotEmpty(storeId)
if (CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.MANAGER.name())
&& CharSequenceUtil.isNotEmpty(storeId)
) {
queryWrapper.eq("store_id", storeId);
}
if (StringUtils.isNotEmpty(memberName)) {
if (CharSequenceUtil.isNotEmpty(memberName)) {
queryWrapper.like("member_name", memberName);
}
if (StringUtils.isNotEmpty(storeName)) {
if (CharSequenceUtil.isNotEmpty(storeName)) {
queryWrapper.like("store_name", storeName);
}
if (StringUtils.isNotEmpty(goodsName)) {
if (CharSequenceUtil.isNotEmpty(goodsName)) {
queryWrapper.like("goods_name", goodsName);
}
//按时间查询
@@ -102,10 +107,10 @@ public class AfterSaleSearchParams extends PageVO {
if (endDate != null) {
queryWrapper.le("create_time", endDate);
}
if (StringUtils.isNotEmpty(serviceStatus)) {
if (CharSequenceUtil.isNotEmpty(serviceStatus)) {
queryWrapper.eq("service_status", serviceStatus);
}
if (StringUtils.isNotEmpty(serviceType)) {
if (CharSequenceUtil.isNotEmpty(serviceType)) {
queryWrapper.eq("service_type", serviceType);
}
this.betweenWrapper(queryWrapper);
@@ -114,20 +119,28 @@ public class AfterSaleSearchParams extends PageVO {
}
private <T> void betweenWrapper(QueryWrapper<T> queryWrapper) {
if (StringUtils.isNotEmpty(applyRefundPrice)) {
if (CharSequenceUtil.isNotEmpty(applyRefundPrice)) {
String[] s = applyRefundPrice.split("_");
if (s.length > 1) {
queryWrapper.ge("apply_refund_price", s[1]);
queryWrapper.between("apply_refund_price", s[0], s[1]);
} else {
queryWrapper.le("apply_refund_price", s[0]);
queryWrapper.ge("apply_refund_price", s[0]);
}
}
if (StringUtils.isNotEmpty(actualRefundPrice)) {
if (CharSequenceUtil.isNotEmpty(actualRefundPrice)) {
String[] s = actualRefundPrice.split("_");
if (s.length > 1) {
queryWrapper.ge("actual_refund_price", s[1]);
queryWrapper.between("actual_refund_price", s[0], s[1]);
} else {
queryWrapper.le("actual_refund_price", s[0]);
queryWrapper.ge("actual_refund_price", s[0]);
}
}
if (CharSequenceUtil.isNotEmpty(flowPrice)) {
String[] s = flowPrice.split("_");
if (s.length > 1) {
queryWrapper.between("flow_price", s[0], s[1]);
} else {
queryWrapper.ge("flow_price", s[0]);
}
}
}

View File

@@ -18,7 +18,6 @@ import java.util.List;
* @since 2020/11/17 7:37 下午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class AfterSaleLogServiceImpl extends ServiceImpl<AfterSaleLogMapper, AfterSaleLog> implements AfterSaleLogService {
@Override

View File

@@ -19,7 +19,6 @@ import java.util.List;
* @since 2020/11/17 7:38 下午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class AfterSaleReasonServiceImpl extends ServiceImpl<AfterSaleReasonMapper, AfterSaleReason> implements AfterSaleReasonService {

View File

@@ -65,7 +65,6 @@ import java.util.stream.Collectors;
* @since 2020/11/17 7:38 下午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class AfterSaleServiceImpl extends ServiceImpl<AfterSaleMapper, AfterSale> implements AfterSaleService {
/**

View File

@@ -106,6 +106,7 @@ public class TradeDTO implements Serializable {
*/
private MemberAddress memberAddress;
/**
* 客户端类型
*/

View File

@@ -3,15 +3,12 @@ package cn.lili.modules.order.cart.entity.vo;
import cn.lili.modules.distribution.entity.dos.DistributionGoods;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.order.cart.entity.enums.CartTypeEnum;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.tools.PromotionTools;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@@ -81,12 +78,6 @@ public class CartSkuVO extends CartBase implements Serializable {
@ApiModelProperty(value = "积分购买 积分数量")
private Long point;
@ApiModelProperty(value = "可参与的单品活动")
private List<PromotionGoods> promotions;
@ApiModelProperty(value = "参与促销活动更新时间(一天更新一次) 例如时间为2020-01-01 000001")
private Date updatePromotionTime;
@ApiModelProperty("商品促销活动集合key 为 促销活动类型value 为 促销活动实体信息 ")
private Map<String, Object> promotionMap;
@@ -104,7 +95,6 @@ public class CartSkuVO extends CartBase implements Serializable {
this.checked = true;
this.invalid = false;
//默认时间为0让系统为此商品更新缓存
this.updatePromotionTime = new Date(0);
this.errorMessage = "";
this.isShip = true;
this.purchasePrice = goodsSku.getPromotionFlag() != null && goodsSku.getPromotionFlag() ? goodsSku.getPromotionPrice() : goodsSku.getPrice();
@@ -125,9 +115,6 @@ public class CartSkuVO extends CartBase implements Serializable {
}
public Map<String, Object> getPromotionMap() {
if (this.promotionMap == null) {
return new HashMap<>();
}
return promotionMap;
return PromotionTools.filterInvalidPromotionsMap(this.promotionMap);
}
}

View File

@@ -62,6 +62,22 @@ public class RenderStepStatement {
RenderStepEnums.DISTRIBUTION,
RenderStepEnums.PLATFORM_COMMISSION
};
/**
* 交易创建前渲染
* 渲染购物车 生成SN 》分销人员佣金渲染 》平台佣金渲染
*/
public static RenderStepEnums[] pintuanTradeRender = {
RenderStepEnums.CHECK_DATA,
RenderStepEnums.SKU_PROMOTION,
RenderStepEnums.COUPON,
RenderStepEnums.SKU_FREIGHT,
RenderStepEnums.CART_PRICE,
RenderStepEnums.CART_SN,
RenderStepEnums.DISTRIBUTION,
RenderStepEnums.PLATFORM_COMMISSION
};
/**
* 交易创建前渲染
* 渲染购物车 生成SN 》分销人员佣金渲染 》平台佣金渲染

View File

@@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
/**
@@ -71,6 +72,8 @@ public class TradeBuilder {
//需要对购物车渲染
if (isSingle(checkedWay)) {
renderCartBySteps(tradeDTO, RenderStepStatement.checkedSingleRender);
} else if (checkedWay.equals(CartTypeEnum.PINTUAN)) {
renderCartBySteps(tradeDTO, RenderStepStatement.pintuanTradeRender);
} else {
renderCartBySteps(tradeDTO, RenderStepStatement.checkedRender);
}
@@ -83,16 +86,16 @@ public class TradeBuilder {
* 1.构造交易
* 2.创建交易
*
* @param checkedWay 购物车类
* @param tradeDTO 交易模
* @return 交易信息
*/
public Trade createTrade(CartTypeEnum checkedWay) {
//读取对应购物车的商品信息
TradeDTO tradeDTO = cartService.readDTO(checkedWay);
public Trade createTrade(TradeDTO tradeDTO) {
//需要对购物车渲染
if (isSingle(checkedWay)) {
if (isSingle(tradeDTO.getCartTypeEnum())) {
renderCartBySteps(tradeDTO, RenderStepStatement.singleTradeRender);
} else if (tradeDTO.getCartTypeEnum().equals(CartTypeEnum.PINTUAN)) {
renderCartBySteps(tradeDTO, RenderStepStatement.pintuanTradeRender);
} else {
renderCartBySteps(tradeDTO, RenderStepStatement.tradeRender);
}
@@ -110,7 +113,7 @@ public class TradeBuilder {
private boolean isSingle(CartTypeEnum checkedWay) {
//拼团 积分 砍价商品
return (checkedWay.equals(CartTypeEnum.PINTUAN) || checkedWay.equals(CartTypeEnum.POINTS) || checkedWay.equals(CartTypeEnum.KANJIA));
return (checkedWay.equals(CartTypeEnum.POINTS) || checkedWay.equals(CartTypeEnum.KANJIA));
}
/**

View File

@@ -1,6 +1,8 @@
package cn.lili.modules.order.cart.render.impl;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
@@ -23,7 +25,6 @@ import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.promotion.entity.dos.Coupon;
import cn.lili.modules.promotion.entity.dos.Pintuan;
import cn.lili.modules.promotion.entity.dos.PointsGoods;
import cn.lili.modules.promotion.entity.dto.BasePromotions;
import cn.lili.modules.promotion.entity.vos.CouponVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -117,16 +118,6 @@ public class CheckDataRender implements CartRenderStep {
//设置失效消息
cartSkuVO.setErrorMessage("商品库存不足,现有库存数量[" + dataSku.getQuantity() + "]");
}
//移除无效促销活动
if (cartSkuVO.getPromotionMap() != null && !cartSkuVO.getPromotionMap().isEmpty()) {
cartSkuVO.setPromotionMap(cartSkuVO.getPromotionMap().entrySet().stream().filter(i -> {
BasePromotions basePromotions = (BasePromotions) i.getValue();
if (basePromotions.getStartTime() != null && basePromotions.getEndTime() != null) {
return basePromotions.getStartTime().getTime() <= System.currentTimeMillis() && basePromotions.getEndTime().getTime() >= System.currentTimeMillis();
}
return true;
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
}
}
}
@@ -151,8 +142,10 @@ public class CheckDataRender implements CartRenderStep {
try {
//筛选属于当前店铺的优惠券
storeCart.getValue().forEach(i -> i.getPromotionMap().forEach((key, value) -> {
if (key.contains(PromotionTypeEnum.COUPON.name()) && ((Coupon) value).getStoreId().equals(storeCart.getKey())) {
cartVO.getCanReceiveCoupon().add(new CouponVO((Coupon) value));
JSONObject promotionsObj = JSONUtil.parseObj(value);
Coupon coupon = JSONUtil.toBean(promotionsObj, Coupon.class);
if (key.contains(PromotionTypeEnum.COUPON.name()) && coupon.getStoreId().equals(storeCart.getKey())) {
cartVO.getCanReceiveCoupon().add(new CouponVO(coupon));
}
}));
} catch (Exception e) {
@@ -189,7 +182,8 @@ public class CheckDataRender implements CartRenderStep {
if (tradeDTO.getSkuList().get(0).getPromotionMap() != null && !tradeDTO.getSkuList().get(0).getPromotionMap().isEmpty()) {
Optional<Map.Entry<String, Object>> pintuanPromotions = tradeDTO.getSkuList().get(0).getPromotionMap().entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst();
if (pintuanPromotions.isPresent()) {
Pintuan pintuan = (Pintuan) pintuanPromotions.get().getValue();
JSONObject promotionsObj = JSONUtil.parseObj(pintuanPromotions.get().getValue());
Pintuan pintuan = promotionsObj.toBean(Pintuan.class);
Integer limitNum = pintuan.getLimitNum();
for (CartSkuVO cartSkuVO : tradeDTO.getSkuList()) {
if (limitNum != 0 && cartSkuVO.getNum() > limitNum) {
@@ -203,7 +197,8 @@ public class CheckDataRender implements CartRenderStep {
//获取积分商品VO
Optional<Map.Entry<String, Object>> pointsPromotions = tradeDTO.getSkuList().get(0).getPromotionMap().entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.POINTS_GOODS.name())).findFirst();
if (pointsPromotions.isPresent()) {
PointsGoods pointsGoods = (PointsGoods) pointsPromotions.get().getValue();
JSONObject promotionsObj = JSONUtil.parseObj(pointsPromotions.get().getValue());
PointsGoods pointsGoods = promotionsObj.toBean(PointsGoods.class);
if (pointsGoods == null) {
throw new ServiceException(ResultCode.POINT_GOODS_ERROR);
}

View File

@@ -1,6 +1,8 @@
package cn.lili.modules.order.cart.render.impl;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.modules.goods.service.CategoryService;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
@@ -64,7 +66,7 @@ public class CommissionRender implements CartRenderStep {
String categoryId = cartSkuVO.getGoodsSku().getCategoryPath()
.substring(cartSkuVO.getGoodsSku().getCategoryPath().lastIndexOf(",") + 1);
if (CharSequenceUtil.isNotEmpty(categoryId)) {
Double commissionRate = categoryService.getById(categoryId).getCommissionRate();
Double commissionRate = categoryService.getCategoryById(categoryId).getCommissionRate();
priceDetailDTO.setPlatFormCommissionPoint(commissionRate);
}
@@ -72,7 +74,8 @@ public class CommissionRender implements CartRenderStep {
if (tradeDTO.getCartTypeEnum().equals(CartTypeEnum.POINTS) && tradeDTO.getSkuList().get(0).getPromotionMap() != null && !tradeDTO.getSkuList().get(0).getPromotionMap().isEmpty()) {
Optional<Map.Entry<String, Object>> pointsPromotions = tradeDTO.getSkuList().get(0).getPromotionMap().entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.POINTS_GOODS.name())).findFirst();
if (pointsPromotions.isPresent()) {
PointsGoods pointsGoods = (PointsGoods) pointsPromotions.get().getValue();
JSONObject promotionsObj = JSONUtil.parseObj(pointsPromotions.get().getValue());
PointsGoods pointsGoods = JSONUtil.toBean(promotionsObj, PointsGoods.class);
priceDetailDTO.setSettlementPrice(pointsGoods.getSettlementPrice());
}
}
@@ -80,7 +83,8 @@ public class CommissionRender implements CartRenderStep {
else if (tradeDTO.getCartTypeEnum().equals(CartTypeEnum.KANJIA) && tradeDTO.getSkuList().get(0).getPromotionMap() != null && !tradeDTO.getSkuList().get(0).getPromotionMap().isEmpty()) {
Optional<Map.Entry<String, Object>> kanjiaPromotions = tradeDTO.getSkuList().get(0).getPromotionMap().entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.KANJIA.name())).findFirst();
if (kanjiaPromotions.isPresent()) {
KanjiaActivityGoods kanjiaActivityGoods = (KanjiaActivityGoods) kanjiaPromotions.get().getValue();
JSONObject promotionsObj = JSONUtil.parseObj(kanjiaPromotions.get().getValue());
KanjiaActivityGoods kanjiaActivityGoods = JSONUtil.toBean(promotionsObj, KanjiaActivityGoods.class);
priceDetailDTO.setSettlementPrice(kanjiaActivityGoods.getSettlementPrice());
}
}

View File

@@ -60,7 +60,7 @@ public class CouponRender implements CartRenderStep {
* @param tradeDTO 交易dto
*/
private void renderCouponRule(TradeDTO tradeDTO) {
List<MemberCoupon> memberCouponList = memberCouponService.getMemberCoupons();
List<MemberCoupon> memberCouponList = memberCouponService.getMemberCoupons(tradeDTO.getMemberId());
if (!memberCouponList.isEmpty()) {
this.checkMemberExistCoupon(tradeDTO, memberCouponList);

View File

@@ -1,5 +1,7 @@
package cn.lili.modules.order.cart.render.impl;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.modules.goods.entity.dos.GoodsSku;
@@ -55,7 +57,8 @@ public class FullDiscountRender implements CartRenderStep {
Optional<Map.Entry<String, Object>> fullDiscountOptional = fullDiscountSkuList.get(0).getPromotionMap().entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.FULL_DISCOUNT.name())).findFirst();
if (fullDiscountOptional.isPresent()) {
FullDiscount fullDiscount = (FullDiscount) fullDiscountOptional.get().getValue();
JSONObject promotionsObj = JSONUtil.parseObj(fullDiscountOptional.get().getValue());
FullDiscount fullDiscount = promotionsObj.toBean(FullDiscount.class);
FullDiscountVO fullDiscountVO = new FullDiscountVO(fullDiscount);
//如果有赠品,则将赠品信息写入

View File

@@ -1,5 +1,7 @@
package cn.lili.modules.order.cart.render.impl;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
@@ -13,10 +15,9 @@ import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.cart.render.CartRenderStep;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.promotion.entity.dto.BasePromotions;
import cn.lili.modules.promotion.entity.dto.search.KanjiaActivitySearchParams;
import cn.lili.modules.promotion.entity.enums.KanJiaStatusEnum;
import cn.lili.modules.promotion.entity.vos.PromotionSkuVO;
import cn.lili.modules.promotion.entity.vos.kanjia.KanjiaActivitySearchParams;
import cn.lili.modules.promotion.entity.vos.kanjia.KanjiaActivityVO;
import cn.lili.modules.promotion.service.KanjiaActivityService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -140,8 +141,8 @@ public class SkuPromotionRender implements CartRenderStep {
continue;
}
BasePromotions basePromotions = (BasePromotions) entry.getValue();
PromotionSkuVO promotionSkuVO = new PromotionSkuVO(entry.getKey().split("-")[0], basePromotions.getId());
JSONObject promotionsObj = JSONUtil.parseObj(entry.getValue());
PromotionSkuVO promotionSkuVO = new PromotionSkuVO(entry.getKey().split("-")[0], promotionsObj.get("id", String.class));
cartSkuVO.setSubTotal(CurrencyUtil.mul(cartSkuVO.getPurchasePrice(), cartSkuVO.getNum()));
cartSkuVO.getPriceDetailDTO().setGoodsPrice(cartSkuVO.getSubTotal());

View File

@@ -1,12 +1,12 @@
package cn.lili.modules.order.cart.service;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.CurrencyUtil;
@@ -31,25 +31,23 @@ import cn.lili.modules.order.cart.render.TradeBuilder;
import cn.lili.modules.order.order.entity.dos.Trade;
import cn.lili.modules.order.order.entity.vo.ReceiptVO;
import cn.lili.modules.promotion.entity.dos.KanjiaActivity;
import cn.lili.modules.promotion.entity.dos.KanjiaActivityGoods;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.dos.Pintuan;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dto.search.KanjiaActivitySearchParams;
import cn.lili.modules.promotion.entity.dto.search.MemberCouponSearchParams;
import cn.lili.modules.promotion.entity.dto.search.PromotionGoodsSearchParams;
import cn.lili.modules.promotion.entity.enums.KanJiaStatusEnum;
import cn.lili.modules.promotion.entity.enums.MemberCouponStatusEnum;
import cn.lili.modules.promotion.entity.enums.PromotionsScopeTypeEnum;
import cn.lili.modules.promotion.entity.vos.PointsGoodsVO;
import cn.lili.modules.promotion.entity.vos.kanjia.KanjiaActivitySearchParams;
import cn.lili.modules.promotion.service.KanjiaActivityService;
import cn.lili.modules.promotion.service.MemberCouponService;
import cn.lili.modules.promotion.service.PointsGoodsService;
import cn.lili.modules.promotion.service.PromotionGoodsService;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.search.service.EsGoodsIndexService;
import cn.lili.modules.search.service.EsGoodsSearchService;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.GoodsTagsEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -113,16 +111,6 @@ public class CartServiceImpl implements CartService {
*/
@Autowired
private KanjiaActivityService kanjiaActivityService;
/**
* rocketMq
*/
@Autowired
private RocketMQTemplate rocketMQTemplate;
/**
* rocketMq配置
*/
@Autowired
private RocketmqCustomProperties rocketmqCustomProperties;
/**
* 交易
*/
@@ -132,6 +120,9 @@ public class CartServiceImpl implements CartService {
@Autowired
private MemberService memberService;
@Autowired
private PromotionGoodsService promotionGoodsService;
@Override
public void add(String skuId, Integer num, String cartType, Boolean cover) {
AuthUser currentUser = Objects.requireNonNull(UserContext.getCurrentUser());
@@ -511,12 +502,11 @@ public class CartServiceImpl implements CartService {
CartTypeEnum cartTypeEnum = getCartType(way);
TradeDTO tradeDTO = this.readDTO(cartTypeEnum);
MemberCoupon memberCoupon =
memberCouponService.getOne(
new LambdaQueryWrapper<MemberCoupon>()
.eq(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name())
.eq(MemberCoupon::getMemberId, currentUser.getId())
.eq(MemberCoupon::getId, couponId));
MemberCouponSearchParams searchParams = new MemberCouponSearchParams();
searchParams.setMemberCouponStatus(MemberCouponStatusEnum.NEW.name());
searchParams.setMemberId(currentUser.getId());
searchParams.setId(couponId);
MemberCoupon memberCoupon = memberCouponService.getMemberCoupon(searchParams);
if (memberCoupon == null) {
throw new ServiceException(ResultCode.COUPON_EXPIRED);
}
@@ -547,10 +537,8 @@ public class CartServiceImpl implements CartService {
if (tradeDTO.getMemberAddress() == null) {
throw new ServiceException(ResultCode.MEMBER_ADDRESS_NOT_EXIST);
}
//将购物车信息写入缓存,后续逻辑调用校验
this.resetTradeDTO(tradeDTO);
//构建交易
Trade trade = tradeBuilder.createTrade(cartTypeEnum);
Trade trade = tradeBuilder.createTrade(tradeDTO);
this.cleanChecked(tradeDTO);
return trade;
}
@@ -560,18 +548,29 @@ public class CartServiceImpl implements CartService {
EsGoodsIndex goodsIndex = goodsIndexService.findById(dataSku.getId());
if (goodsIndex == null) {
GoodsVO goodsVO = this.goodsService.getGoodsVO(dataSku.getGoodsId());
goodsIndex = goodsIndexService.getTempEsGoodsIndex(dataSku, goodsVO.getGoodsParamsDTOList());
//发送mq消息
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.RESET_GOODS_INDEX.name();
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(Collections.singletonList(goodsIndex)), RocketmqSendCallbackBuilder.commonCallback());
goodsIndex = goodsIndexService.getResetEsGoodsIndex(dataSku, goodsVO.getGoodsParamsDTOList());
}
if (goodsIndex.getPromotionMap() != null && !goodsIndex.getPromotionMap().isEmpty()) {
if (goodsIndex.getPromotionMap().keySet().stream().anyMatch(i -> i.contains(PromotionTypeEnum.SECKILL.name())) ||
(goodsIndex.getPromotionMap().keySet().stream().anyMatch(i -> i.contains(PromotionTypeEnum.PINTUAN.name()))
&& CartTypeEnum.PINTUAN.name().equals(cartType))) {
dataSku.setPromotionFlag(true);
dataSku.setPromotionPrice(goodsIndex.getPromotionPrice());
Optional<Map.Entry<String, Object>> containsPromotion = goodsIndex.getPromotionMap().entrySet().stream().filter(i ->
i.getKey().contains(PromotionTypeEnum.SECKILL.name()) || i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst();
if (containsPromotion.isPresent()) {
JSONObject promotionsObj = JSONUtil.parseObj(containsPromotion.get().getValue());
PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
searchParams.setSkuId(dataSku.getId());
searchParams.setPromotionId(promotionsObj.get("id").toString());
PromotionGoods promotionsGoods = promotionGoodsService.getPromotionsGoods(searchParams);
if (promotionsGoods != null && promotionsGoods.getPrice() != null) {
dataSku.setPromotionFlag(true);
dataSku.setPromotionPrice(promotionsGoods.getPrice());
} else {
dataSku.setPromotionFlag(false);
dataSku.setPromotionPrice(null);
}
}
}
promotionMap = goodsIndex.getPromotionMap();
} else {
@@ -672,13 +671,13 @@ public class CartServiceImpl implements CartService {
return cartSkuVOS;
} else if (memberCoupon.getScopeType().equals(PromotionsScopeTypeEnum.PORTION_GOODS_CATEGORY.name())) {
//分类路径是否包含
return cartSkuVOS.stream().filter(i -> i.getGoodsSku().getCategoryPath().indexOf("," + memberCoupon.getScopeId() + ",") <= 0).collect(Collectors.toList());
return cartSkuVOS.stream().filter(i -> CharSequenceUtil.contains(memberCoupon.getScopeId(), i.getGoodsSku().getCategoryPath())).collect(Collectors.toList());
} else if (memberCoupon.getScopeType().equals(PromotionsScopeTypeEnum.PORTION_GOODS.name())) {
//范围关联ID是否包含
return cartSkuVOS.stream().filter(i -> memberCoupon.getScopeId().indexOf("," + i.getGoodsSku().getId() + ",") <= 0).collect(Collectors.toList());
return cartSkuVOS.stream().filter(i -> CharSequenceUtil.contains(memberCoupon.getScopeId(), i.getGoodsSku().getId())).collect(Collectors.toList());
} else if (memberCoupon.getScopeType().equals(PromotionsScopeTypeEnum.PORTION_SHOP_CATEGORY.name())) {
//店铺分类路径是否包含
return cartSkuVOS.stream().filter(i -> i.getGoodsSku().getStoreCategoryPath().indexOf("," + memberCoupon.getScopeId() + ",") <= 0).collect(Collectors.toList());
return cartSkuVOS.stream().filter(i -> CharSequenceUtil.contains(memberCoupon.getScopeId(), i.getGoodsSku().getStoreCategoryPath())).collect(Collectors.toList());
}
return new ArrayList<>();
}
@@ -718,11 +717,11 @@ public class CartServiceImpl implements CartService {
if (cartSkuVO.getPromotionMap() != null && !cartSkuVO.getPromotionMap().isEmpty()) {
Optional<Map.Entry<String, Object>> pintuanPromotions = cartSkuVO.getPromotionMap().entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst();
if (pintuanPromotions.isPresent()) {
Pintuan pintuan = (Pintuan) pintuanPromotions.get().getValue();
JSONObject promotionsObj = JSONUtil.parseObj(pintuanPromotions.get().getValue());
//写入拼团信息
cartSkuVO.setPintuanId(pintuan.getId());
cartSkuVO.setPintuanId(promotionsObj.get("id").toString());
//检测拼团限购数量
Integer limitNum = pintuan.getLimitNum();
Integer limitNum = promotionsObj.get("limitNum", Integer.class);
if (limitNum != 0 && cartSkuVO.getNum() > limitNum) {
throw new ServiceException(ResultCode.CART_PINTUAN_LIMIT_ERROR);
}
@@ -739,10 +738,10 @@ public class CartServiceImpl implements CartService {
if (cartSkuVO.getPromotionMap() != null && !cartSkuVO.getPromotionMap().isEmpty()) {
Optional<Map.Entry<String, Object>> kanjiaPromotions = cartSkuVO.getPromotionMap().entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.KANJIA.name())).findFirst();
if (kanjiaPromotions.isPresent()) {
KanjiaActivityGoods kanjiaActivityGoods = (KanjiaActivityGoods) kanjiaPromotions.get().getValue();
JSONObject promotionsObj = JSONUtil.parseObj(kanjiaPromotions.get().getValue());
//查找当前会员的砍价商品活动
KanjiaActivitySearchParams kanjiaActivitySearchParams = new KanjiaActivitySearchParams();
kanjiaActivitySearchParams.setKanjiaActivityGoodsId(kanjiaActivityGoods.getId());
kanjiaActivitySearchParams.setKanjiaActivityGoodsId(promotionsObj.get("id", String.class));
kanjiaActivitySearchParams.setMemberId(UserContext.getCurrentUser().getId());
kanjiaActivitySearchParams.setStatus(KanJiaStatusEnum.SUCCESS.name());
KanjiaActivity kanjiaActivity = kanjiaActivityService.getKanjiaActivity(kanjiaActivitySearchParams);

View File

@@ -1,5 +1,6 @@
package cn.lili.modules.order.order.entity.dos;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.mybatis.BaseEntity;
import cn.lili.common.utils.BeanUtil;
import cn.lili.modules.order.cart.entity.enums.DeliveryMethodEnum;
@@ -82,6 +83,7 @@ public class Trade extends BaseEntity {
}
BeanUtil.copyProperties(tradeDTO, this);
BeanUtil.copyProperties(tradeDTO.getPriceDetailDTO(), this);
this.setPayStatus(PayStatusEnum.UNPAID.name());
this.setId(originId);
}
}

View File

@@ -106,6 +106,9 @@ public class OrderSearchParams extends PageVO {
@ApiModelProperty(value = "是否为某订单类型的订单如果是则为订单类型的id否则为空")
private String promotionId;
@ApiModelProperty(value = "总价格,可以为范围如10_1000")
private String flowPrice;
/**
* @see OrderPromotionTypeEnum
*/
@@ -209,6 +212,14 @@ public class OrderSearchParams extends PageVO {
wrapper.eq(CharSequenceUtil.isNotEmpty(orderPromotionType), "o.order_promotion_type", orderPromotionType);
if (CharSequenceUtil.isNotEmpty(flowPrice)) {
String[] s = flowPrice.split("_");
if (s.length > 1) {
wrapper.between("o.flow_price", s[0], s[1]);
} else {
wrapper.ge("o.flow_price", s[0]);
}
}
wrapper.eq("o.delete_flag", false);
return wrapper;
}

View File

@@ -170,7 +170,7 @@ public class PriceDetailDTO implements Serializable {
billPrice = settlementPrice;
} else {
//如果是普通订单最终结算金额 = flowPrice - platFormCommission - distributionCommission 流水金额-平台佣金-分销佣金
billPrice = CurrencyUtil.sub(CurrencyUtil.sub(flowPrice, platFormCommission), distributionCommission);
billPrice = CurrencyUtil.sub(flowPrice, platFormCommission, distributionCommission);
}
}
@@ -309,7 +309,7 @@ public class PriceDetailDTO implements Serializable {
}
public Double getUpdatePrice() {
if (updatePrice == null || updatePrice <= 0) {
if (updatePrice == null) {
return 0D;
}
return updatePrice;

View File

@@ -16,5 +16,10 @@ public enum OrderTypeEnum {
/**
* 虚拟订单
*/
VIRTUAL
VIRTUAL,
/**
* 虚拟订单
*/
E_COUPON,
}

View File

@@ -0,0 +1,33 @@
package cn.lili.modules.order.order.entity.enums;
/**
* 交易状态枚举
*
* @author Chopper
* @since 2020/11/17 7:27 下午
*/
public enum TradeStatusEnum {
/**
* 交易状态
*/
UNPAID("未付款"),
PAID("已付款"),
CANCELLED("已取消");
private final String description;
TradeStatusEnum(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public String description() {
return this.description;
}
}

View File

@@ -24,7 +24,6 @@ import java.util.List;
* @since 2020/11/17 7:38 下午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class OrderItemServiceImpl extends ServiceImpl<OrderItemMapper, OrderItem> implements OrderItemService {
@Override

View File

@@ -16,6 +16,7 @@ import cn.lili.modules.order.order.service.OrderPriceService;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.payment.kit.plugin.bank.BankTransferPlugin;
import cn.lili.modules.system.aspect.annotation.SystemLogPoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -29,8 +30,8 @@ import java.util.List;
* @author Chopper
* @since 2020/11/17 7:36 下午
*/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class OrderPriceServiceImpl implements OrderPriceService {
/**
@@ -107,10 +108,8 @@ public class OrderPriceServiceImpl implements OrderPriceService {
//订单修改金额=使用订单原始金额-修改后金额
orderPriceDetailDTO.setUpdatePrice(CurrencyUtil.sub(orderPrice, orderPriceDetailDTO.getOriginalPrice()));
order.setFlowPrice(orderPriceDetailDTO.getFlowPrice());
order.setPriceDetail(JSONUtil.toJsonStr(orderPriceDetailDTO));
//修改订单
order.setPriceDetail(JSONUtil.toJsonStr(orderPriceDetailDTO));
order.setPriceDetailDTO(orderPriceDetailDTO);
orderService.updateById(order);
//修改子订单

View File

@@ -85,7 +85,6 @@ import java.util.stream.Collectors;
* @since 2020/11/17 7:38 下午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
private static final String ORDER_SN_COLUMN = "order_sn";
@@ -145,6 +144,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
private TradeService tradeService;
@Override
@Transactional(rollbackFor = Exception.class)
public void intoDB(TradeDTO tradeDTO) {
//检查TradeDTO信息
checkTradeDTO(tradeDTO);
@@ -367,7 +367,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
//判断是否为拼团订单,进行特殊处理
//判断订单类型进行不同的订单确认操作
if (OrderPromotionTypeEnum.PINTUAN.name().equals(order.getOrderPromotionType())) {
this.checkPintuanOrder(order.getPromotionId(), order.getParentOrderSn());
String parentOrderSn = CharSequenceUtil.isEmpty(order.getParentOrderSn()) ? orderSn : order.getParentOrderSn();
this.checkPintuanOrder(order.getPromotionId(), parentOrderSn);
} else {
//判断订单类型
if (order.getOrderType().equals(OrderTypeEnum.NORMAL.name())) {
@@ -489,6 +490,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
//修改订单货物可以进行评价
orderItemService.update(new UpdateWrapper<OrderItem>().eq(ORDER_SN_COLUMN, orderSn)
.set("comment_status", CommentStatusEnum.UNFINISHED));
this.update(new LambdaUpdateWrapper<Order>().eq(Order::getSn, orderSn).set(Order::getCompleteTime, new Date()));
//发送订单状态改变消息
OrderMessage orderMessage = new OrderMessage();
orderMessage.setNewStatus(OrderStatusEnum.COMPLETED);
@@ -640,7 +642,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
public Double getPaymentTotal(String orderSn) {
Order order = this.getBySn(orderSn);
Trade trade = tradeService.getBySn(order.getTradeSn());
if (trade.getPayStatus().equals(PayStatusEnum.PAID.name())) {
//如果交易不为空,则返回交易的金额,否则返回订单金额
if (StringUtils.isNotEmpty(trade.getPayStatus())
&& trade.getPayStatus().equals(PayStatusEnum.PAID.name())) {
return trade.getFlowPrice();
}
return order.getFlowPrice();
@@ -788,10 +792,6 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
* @param parentOrderSn 拼团父订单编号
*/
private void checkPintuanOrder(String pintuanId, String parentOrderSn) {
//拼团有效参数判定
if (CharSequenceUtil.isEmpty(parentOrderSn)) {
return;
}
//获取拼团配置
Pintuan pintuan = pintuanService.getById(pintuanId);
List<Order> list = this.getPintuanOrder(pintuanId, parentOrderSn);
@@ -799,7 +799,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
if (count == 1) {
//如果为开团订单,则发布一个一小时的延时任务,时间到达后,如果未成团则自动结束(未开启虚拟成团的情况下)
PintuanOrderMessage pintuanOrderMessage = new PintuanOrderMessage();
long startTime = DateUtil.offsetHour(new Date(), 1).getTime();
//开团结束时间
// long startTime = DateUtil.offsetHour(new Date(), 1).getTime();
long startTime = DateUtil.offsetMinute(new Date(), 2).getTime();
pintuanOrderMessage.setOrderSn(parentOrderSn);
pintuanOrderMessage.setPintuanId(pintuanId);
TimeTriggerMsg timeTriggerMsg = new TimeTriggerMsg(TimeExecuteConstant.PROMOTION_EXECUTOR,
@@ -884,22 +886,6 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
}
}
/**
* 检查交易信息
*
* @param order 订单
*/
private void checkOrder(Order order) {
//订单类型为拼团订单,检测购买数量是否超过了限购数量
if (OrderPromotionTypeEnum.PINTUAN.name().equals(order.getOrderType())) {
Pintuan pintuan = pintuanService.getById(order.getPromotionId());
Integer limitNum = pintuan.getLimitNum();
if (limitNum != 0 && order.getGoodsNum() > limitNum) {
throw new ServiceException(ResultCode.PINTUAN_LIMIT_NUM_ERROR);
}
}
}
/**
* 普通商品订单确认
* 修改订单状态为待发货

View File

@@ -44,7 +44,6 @@ import java.util.List;
*/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class StoreFlowServiceImpl extends ServiceImpl<StoreFlowMapper, StoreFlow> implements StoreFlowService {
/**
@@ -160,7 +159,7 @@ public class StoreFlowServiceImpl extends ServiceImpl<StoreFlowMapper, StoreFlow
//流水金额
storeFlow.setFinalPrice(afterSale.getActualRefundPrice());
//最终结算金额
storeFlow.setBillPrice(CurrencyUtil.add(CurrencyUtil.add(storeFlow.getFinalPrice(), storeFlow.getDistributionRebate()), storeFlow.getCommissionPrice()));
storeFlow.setBillPrice(CurrencyUtil.add(storeFlow.getFinalPrice(), storeFlow.getDistributionRebate(), storeFlow.getCommissionPrice()));
//获取第三方支付流水号
RefundLog refundLog = refundLogService.queryByAfterSaleSn(afterSale.getSn());
storeFlow.setTransactionId(refundLog.getReceivableNo());

File diff suppressed because one or more lines are too long

View File

@@ -29,7 +29,6 @@ import java.util.List;
* @since 2020-05-5 15:10:16
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class ArticleCategoryServiceImpl extends ServiceImpl<ArticleCategoryMapper, ArticleCategory> implements ArticleCategoryService {
/**

View File

@@ -30,7 +30,6 @@ import java.util.List;
* @since 2020/11/18 11:40 上午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {
@Override

View File

@@ -17,7 +17,6 @@ import org.springframework.transaction.annotation.Transactional;
* @since 2020/11/18 11:40 上午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class FeedbackServiceImpl extends ServiceImpl<FeedbackMapper, Feedback> implements FeedbackService {
}

View File

@@ -5,6 +5,8 @@ import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.payment.kit.core.PaymentHttpResponse;
import cn.lili.modules.payment.kit.core.enums.RequestMethodEnums;
import cn.lili.modules.payment.kit.core.enums.SignType;
@@ -114,6 +116,30 @@ public class WxPayKit {
}
}
/**
* APP 单独生成签名
* app 支付环境中,如果遇到签名错误,百思不得其解,则可以使用这个方法调用签名尝试解决
*
* @param params 需要签名的参数
* @return 签名后的数据
*/
public static String createAppSign(Map<String, String> params, String privateKey) {
String appid = params.get("appid");
String timestamp = params.get("timestamp");
String noncestr = params.get("noncestr");
String prepayid = params.get("prepayid");
String encrypt = appid + "\n" + timestamp + "\n" + noncestr + "\n" + prepayid + "\n";
try {
return PayKit.createSign(encrypt, privateKey);
} catch (Exception e) {
throw new ServiceException(ResultCode.ERROR);
}
}
/**
* 生成签名
*
@@ -351,6 +377,8 @@ public class WxPayKit {
signType = SignType.MD5;
}
String packageSign = createSign(packageParams, partnerKey, signType);
// 部分微信APP支付 提示签名错误 解开下方注释 替换上边的代码就好。
// String packageSign = createAppSign(packageParams, partnerKey);
packageParams.put("sign", packageSign);
return packageParams;
}

View File

@@ -273,7 +273,7 @@ public class AliPayPlugin implements Payment {
log.info("支付回调通知:支付失败-参数:{}", map);
}
ThreadContextHolder.getHttpResponse().sendRedirect(domainProperties.getWap()+"/pages/order/myOrder?status=0");
ThreadContextHolder.getHttpResponse().sendRedirect(domainProperties.getWap() + "/pages/order/myOrder?status=0");
} catch (Exception e) {
log.error("支付回调同步通知异常", e);
}
@@ -293,7 +293,11 @@ public class AliPayPlugin implements Payment {
log.info("支付回调响应:{}", JSONUtil.toJsonStr(map));
boolean verifyResult = AlipaySignature.rsaCertCheckV1(map, alipayPaymentSetting.getAlipayPublicCertPath(), "UTF-8",
"RSA2");
//支付完成判定
if (!"TRADE_FINISHED".equals(map.get("trade_status")) &&
!"TRADE_SUCCESS".equals(map.get("trade_status"))) {
return;
}
String payParamStr = map.get("passback_params");
String payParamJson = URLDecoder.decode(payParamStr, StandardCharsets.UTF_8);
PayParam payParam = BeanUtil.formatKeyValuePair(payParamJson, new PayParam());

View File

@@ -19,6 +19,8 @@ import cn.lili.modules.wallet.entity.dto.MemberWalletUpdateDTO;
import cn.lili.modules.wallet.entity.enums.DepositServiceTypeEnum;
import cn.lili.modules.wallet.service.MemberWalletService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -57,9 +59,11 @@ public class WalletPlugin implements Payment {
@Autowired
private CashierSupport cashierSupport;
@Autowired
private RedissonClient redisson;
@Override
public ResultMessage<Object> h5pay(HttpServletRequest request, HttpServletResponse response, PayParam payParam) {
savePaymentLog(payParam);
return ResultUtil.success(ResultCode.PAY_SUCCESS);
}
@@ -113,9 +117,18 @@ public class WalletPlugin implements Payment {
* @param payParam 支付参数
*/
private void savePaymentLog(PayParam payParam) {
//获取支付收银参数
CashierParam cashierParam = cashierSupport.cashierParam(payParam);
this.callBack(payParam, cashierParam);
//同一个会员如果在不同的客户端使用预存款支付,会存在同时支付,无法保证预存款的正确性,所以对会员加锁
RLock lock = redisson.getLock(UserContext.getCurrentUser().getId() + "");
lock.lock();
try {
//获取支付收银参数
CashierParam cashierParam = cashierSupport.cashierParam(payParam);
this.callBack(payParam, cashierParam);
} catch (Exception e) {
throw e;
} finally {
lock.unlock();
}
}
@Override

View File

@@ -39,7 +39,6 @@ import cn.lili.modules.payment.kit.plugin.wechat.model.*;
import cn.lili.modules.payment.service.PaymentService;
import cn.lili.modules.payment.service.RefundLogService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.connect.dto.WechatConnectSettingItem;
import cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
@@ -397,10 +396,9 @@ public class WechatPlugin implements Payment {
//微信小程序appid 需要单独获取这里读取了联合登陆配置的appid 实际场景小程序自动登录所以这个appid是最为保险的做法
//如果有2开需求这里需要调整修改这个appid的获取途径即可
String appid = wechatPaymentSetting().getMpAppId();
if (appid == null) {
if (StringUtils.isEmpty(appid)) {
throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
}
String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam), StandardCharsets.UTF_8);
WechatPaymentSetting setting = wechatPaymentSetting();

View File

@@ -19,7 +19,6 @@ import java.util.List;
*/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class PaymentServiceImpl implements PaymentService {
@Autowired

View File

@@ -15,7 +15,6 @@ import org.springframework.transaction.annotation.Transactional;
* @since 2020-12-19 09:25
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class RefundLogServiceImpl extends ServiceImpl<RefundLogMapper, RefundLog> implements RefundLogService {
@Override

View File

@@ -42,7 +42,6 @@ import java.util.stream.Collectors;
*/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser> implements AdminUserService {
@Autowired
private UserRoleService userRoleService;
@@ -119,7 +118,7 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
throw new ServiceException(ResultCode.USER_PASSWORD_ERROR);
}
try {
return managerTokenGenerate.createToken(username, false);
return managerTokenGenerate.createToken(adminUser, false);
} catch (Exception e) {
log.error("管理员登录错误", e);
}

View File

@@ -17,7 +17,6 @@ import java.util.List;
* @since 2020/11/22 12:08
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class DepartmentRoleServiceImpl extends ServiceImpl<DepartmentRoleMapper, DepartmentRole> implements DepartmentRoleService {

Some files were not shown because too many files have changed in this diff Show More