Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop into fengtianyangyang_clerk
Conflicts: DB/version4.2.3toMASTER.sql common-api/src/main/java/cn/lili/controller/common/SiteController.java common-api/src/main/java/cn/lili/controller/common/UploadController.java config/application.yml framework/src/main/java/cn/lili/modules/goods/entity/dos/Goods.java framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberServiceImpl.java framework/src/main/java/cn/lili/modules/order/order/serviceimpl/OrderServiceImpl.java framework/src/main/java/cn/lili/modules/page/serviceimpl/PageDataServiceImpl.java
This commit is contained in:
@@ -465,16 +465,19 @@ public enum CachePrefix {
|
||||
*/
|
||||
INIT_INDEX_FLAG,
|
||||
|
||||
/**
|
||||
* 店铺
|
||||
*/
|
||||
STORE,
|
||||
/**
|
||||
* 店铺分类
|
||||
*/
|
||||
STORE_CATEGORY,
|
||||
/**
|
||||
* 用户菜单
|
||||
*/
|
||||
MENU_USER_ID,
|
||||
/**
|
||||
* 用户菜单
|
||||
* <p>
|
||||
* 这个缓存并非永久缓存,而是300秒缓存,也就是说修改用户关联的部门,关联的角色,
|
||||
* 部门关联的角色,角色关联的菜单等等,最多需要5分钟才能生效
|
||||
*/
|
||||
STORE_MENU_USER_ID,
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.SerializationException;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 要实现对象的缓存,定义自己的序列化和反序列化器。使用阿里的fastjson来实现的比较多
|
||||
@@ -13,8 +14,8 @@ import java.nio.charset.Charset;
|
||||
* @author Bulbasaur
|
||||
*/
|
||||
public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
|
||||
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
|
||||
private Class<T> clazz;
|
||||
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
|
||||
private final Class<T> clazz;
|
||||
|
||||
public FastJsonRedisSerializer(Class<T> clazz) {
|
||||
super();
|
||||
@@ -26,7 +27,10 @@ public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
|
||||
if (null == t) {
|
||||
return new byte[0];
|
||||
}
|
||||
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
|
||||
return JSON.toJSONString(t,
|
||||
SerializerFeature.WriteClassName,
|
||||
SerializerFeature.DisableCircularReferenceDetect)
|
||||
.getBytes(DEFAULT_CHARSET);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.redisson.config.ClusterServersConfig;
|
||||
import org.redisson.config.Config;
|
||||
import org.redisson.config.SentinelServersConfig;
|
||||
import org.redisson.config.SingleServerConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@@ -56,13 +55,11 @@ import java.util.Map;
|
||||
public class RedisConfig extends CachingConfigurerSupport {
|
||||
|
||||
|
||||
private static final String REDIS_PREFIX = "redis://";
|
||||
|
||||
@Value("${lili.cache.timeout:7200}")
|
||||
private Integer timeout;
|
||||
|
||||
@Autowired
|
||||
private RedisProperties redisProperties;
|
||||
|
||||
|
||||
/**
|
||||
* 当有多个管理器的时候,必须使用该注解在一个管理器上注释:表示该管理器为默认的管理器
|
||||
*
|
||||
@@ -101,7 +98,7 @@ public class RedisConfig extends CachingConfigurerSupport {
|
||||
public RedisTemplate<Object, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
|
||||
RedisTemplate<Object, Object> template = new RedisTemplate<>();
|
||||
//使用fastjson序列化
|
||||
FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
|
||||
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
|
||||
//value值的序列化采用fastJsonRedisSerializer
|
||||
template.setValueSerializer(fastJsonRedisSerializer);
|
||||
template.setHashValueSerializer(fastJsonRedisSerializer);
|
||||
@@ -113,16 +110,15 @@ public class RedisConfig extends CachingConfigurerSupport {
|
||||
}
|
||||
|
||||
@Bean(destroyMethod = "shutdown")
|
||||
public RedissonClient redisson() {
|
||||
public RedissonClient redisson(RedisProperties redisProperties) {
|
||||
Config config = new Config();
|
||||
|
||||
if (redisProperties.getSentinel() != null && !redisProperties.getSentinel().getNodes().isEmpty()) {
|
||||
// 哨兵模式
|
||||
SentinelServersConfig sentinelServersConfig = config.useSentinelServers();
|
||||
sentinelServersConfig.setMasterName(redisProperties.getSentinel().getMaster());
|
||||
List<String> sentinelAddress = new ArrayList<>();
|
||||
for (String node : redisProperties.getCluster().getNodes()) {
|
||||
sentinelAddress.add("redis://" + node);
|
||||
sentinelAddress.add(REDIS_PREFIX + node);
|
||||
}
|
||||
sentinelServersConfig.setSentinelAddresses(sentinelAddress);
|
||||
if (CharSequenceUtil.isNotEmpty(redisProperties.getSentinel().getPassword())) {
|
||||
@@ -133,7 +129,7 @@ public class RedisConfig extends CachingConfigurerSupport {
|
||||
ClusterServersConfig clusterServersConfig = config.useClusterServers();
|
||||
List<String> clusterNodes = new ArrayList<>();
|
||||
for (String node : redisProperties.getCluster().getNodes()) {
|
||||
clusterNodes.add("redis://" + node);
|
||||
clusterNodes.add(REDIS_PREFIX + node);
|
||||
}
|
||||
clusterServersConfig.setNodeAddresses(clusterNodes);
|
||||
if (CharSequenceUtil.isNotEmpty(redisProperties.getPassword())) {
|
||||
@@ -141,10 +137,11 @@ public class RedisConfig extends CachingConfigurerSupport {
|
||||
}
|
||||
} else {
|
||||
SingleServerConfig singleServerConfig = config.useSingleServer();
|
||||
singleServerConfig.setAddress("redis://" + redisProperties.getHost() + ":" + redisProperties.getPort());
|
||||
singleServerConfig.setAddress(REDIS_PREFIX + redisProperties.getHost() + ":" + redisProperties.getPort());
|
||||
if (CharSequenceUtil.isNotEmpty(redisProperties.getPassword())) {
|
||||
singleServerConfig.setPassword(redisProperties.getPassword());
|
||||
}
|
||||
singleServerConfig.setPingConnectionInterval(1000);
|
||||
}
|
||||
|
||||
return Redisson.create(config);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.lili.common.aop.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 异常重试注解
|
||||
*
|
||||
* @author paulG
|
||||
* @since 2022/4/26
|
||||
**/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
public @interface RetryOperation {
|
||||
/**
|
||||
* 重试次数
|
||||
*/
|
||||
int retryCount() default 3;
|
||||
|
||||
/**
|
||||
* 重试间隔
|
||||
*/
|
||||
int waitSeconds() default 10;
|
||||
}
|
||||
@@ -1,13 +1,5 @@
|
||||
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;
|
||||
@@ -23,6 +15,13 @@ import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 防重复提交业务
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v1.0
|
||||
* 2022-01-25 09:20
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -37,8 +36,8 @@ public class PreventDuplicateSubmissionsInterceptor {
|
||||
|
||||
try {
|
||||
Long count = cache.incr(getParams(), preventDuplicateSubmissions.expire());
|
||||
//如果超过1或者设置的参数,则表示重复提交了
|
||||
if (count.intValue() >= preventDuplicateSubmissions.expire()) {
|
||||
//如果超过2或者设置的参数,则表示重复提交了
|
||||
if (count.intValue() >= 2) {
|
||||
throw new ServiceException(ResultCode.LIMIT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package cn.lili.common.aop.interceptor;
|
||||
|
||||
import cn.lili.common.aop.annotation.RetryOperation;
|
||||
import cn.lili.common.exception.RetryException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author paulG
|
||||
* @since 2022/4/26
|
||||
**/
|
||||
@Aspect
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RetryAspect {
|
||||
|
||||
|
||||
@Around(value = "@annotation(retryOperation)")
|
||||
public Object retryOperation(ProceedingJoinPoint joinPoint, RetryOperation retryOperation) throws Throwable {
|
||||
|
||||
Object response = null;
|
||||
int retryCount = retryOperation.retryCount();
|
||||
int waitSeconds = retryOperation.waitSeconds();
|
||||
boolean successful = false;
|
||||
|
||||
do {
|
||||
try {
|
||||
response = joinPoint.proceed();
|
||||
successful = true;
|
||||
} catch (RetryException ex) {
|
||||
log.info("Operation failed, retries remaining: {}", retryCount);
|
||||
retryCount--;
|
||||
if (retryCount < 0) {
|
||||
successful = true;
|
||||
log.error(ex.getMessage());
|
||||
}
|
||||
if (waitSeconds > 0 && !successful) {
|
||||
log.info("Waiting for {} second(s) before next retry", waitSeconds);
|
||||
Thread.sleep(waitSeconds * 1000L);
|
||||
}
|
||||
}
|
||||
} while (!successful);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,6 +40,7 @@ public enum ResultCode {
|
||||
FILE_TYPE_NOT_SUPPORT(1010, "不支持上传的文件类型!"),
|
||||
PLATFORM_NOT_SUPPORTED_IM(1006, "平台未开启IM"),
|
||||
STORE_NOT_SUPPORTED_IM(1007, "店铺未开启IM"),
|
||||
UNINITIALIZED_PASSWORD(1008, "非初始化密码,无法进行初始化设置"),
|
||||
/**
|
||||
* 分类
|
||||
*/
|
||||
@@ -75,9 +76,13 @@ public enum ResultCode {
|
||||
GOODS_SKU_QUANTITY_ERROR(11011, "商品库存数量不能为负数"),
|
||||
GOODS_SKU_QUANTITY_NOT_ENOUGH(11011, "商品库存不足"),
|
||||
MUST_HAVE_GOODS_SKU(11012, "规格必须要有一个!"),
|
||||
MUST_HAVE_SALES_MODEL(11022, "销售模式为批发时必须要有批发规则!"),
|
||||
|
||||
HAVE_INVALID_SALES_MODEL(11023, "批发规则存在小于等于0的无效数据!"),
|
||||
|
||||
GOODS_PARAMS_ERROR(11013, "商品参数错误,刷新后重试"),
|
||||
PHYSICAL_GOODS_NEED_TEMP(11014, "实物商品需选择配送模板"),
|
||||
VIRTUAL_GOODS_NOT_NEED_TEMP(11015, "实物商品需选择配送模板"),
|
||||
VIRTUAL_GOODS_NOT_NEED_TEMP(11015, "虚拟商品无需选择配送模板"),
|
||||
GOODS_NOT_EXIST_STORE(11017, "当前用户无权操作此商品"),
|
||||
GOODS_TYPE_ERROR(11016, "需选择商品类型"),
|
||||
|
||||
@@ -187,6 +192,7 @@ public enum ResultCode {
|
||||
MEMBER_ADDRESS_NOT_EXIST(31009, "订单无收货地址,请先配置收货地址"),
|
||||
ORDER_DELIVER_NUM_ERROR(31010, "没有待发货的订单"),
|
||||
ORDER_NOT_SUPPORT_DISTRIBUTION(31011, "购物车中包含不支持配送的商品,请重新选择收货地址,或者重新选择商品"),
|
||||
ORDER_NOT_EXIST_VALID(31041, "购物车中无有效商品,请检查购物车内商品,或者重新选择商品"),
|
||||
ORDER_CAN_NOT_CANCEL(31012, "当前订单状态不可取消"),
|
||||
ORDER_BATCH_DELIVER_ERROR(31013, "批量发货,文件读取失败"),
|
||||
ORDER_ITEM_NOT_EXIST(31014, "当前订单项不存在!"),
|
||||
@@ -258,6 +264,7 @@ public enum ResultCode {
|
||||
*/
|
||||
PROMOTION_GOODS_NOT_EXIT(40000, "当前促销商品不存在!"),
|
||||
PROMOTION_GOODS_QUANTITY_NOT_EXIT(40020, "当前促销商品库存不足!"),
|
||||
PROMOTION_GOODS_DO_NOT_JOIN_WHOLESALE(40050, "批发商品无法参加促销"),
|
||||
PROMOTION_SAME_ACTIVE_EXIST(40001, "活动时间内已存在同类活动,请选择关闭、删除当前时段的活动"),
|
||||
PROMOTION_START_TIME_ERROR(40002, "活动起始时间不能小于当前时间"),
|
||||
PROMOTION_END_TIME_ERROR(40003, "活动结束时间不能小于当前时间"),
|
||||
@@ -282,11 +289,6 @@ public enum ResultCode {
|
||||
COUPON_RECEIVE_ERROR(41005, "当前优惠券已经被领取完了,下次要早点来哦"),
|
||||
COUPON_NUM_INSUFFICIENT_ERROR(41006, "优惠券剩余领取数量不足"),
|
||||
COUPON_NOT_EXIST(41007, "当前优惠券不存在"),
|
||||
COUPON_DO_NOT_RECEIVER(41030, "当前优惠券不允许主动领取"),
|
||||
COUPON_ACTIVITY_NOT_EXIST(410022, "当前优惠券活动不存在"),
|
||||
COUPON_SAVE_ERROR(41020, "保存优惠券失败"),
|
||||
COUPON_ACTIVITY_SAVE_ERROR(41023, "保存优惠券活动失败"),
|
||||
COUPON_DELETE_ERROR(41021, "删除优惠券失败"),
|
||||
COUPON_LIMIT_NUM_LESS_THAN_0(41008, "领取限制数量不能为负数"),
|
||||
COUPON_LIMIT_GREATER_THAN_PUBLISH(41009, "领取限制数量超出发行数量"),
|
||||
COUPON_DISCOUNT_ERROR(41010, "优惠券折扣必须小于10且大于0"),
|
||||
@@ -297,6 +299,15 @@ public enum ResultCode {
|
||||
COUPON_MEMBER_NOT_EXIST(41015, "没有当前会员优惠券"),
|
||||
COUPON_MEMBER_STATUS_ERROR(41016, "当前会员优惠券已过期/作废无法变更状态!"),
|
||||
|
||||
SPECIAL_CANT_USE(41019, "特殊商品不能使用优惠券,不能使用"),
|
||||
|
||||
COUPON_SAVE_ERROR(41020, "保存优惠券失败"),
|
||||
COUPON_DELETE_ERROR(41021, "删除优惠券失败"),
|
||||
COUPON_ACTIVITY_NOT_EXIST(41022, "当前优惠券活动不存在"),
|
||||
COUPON_ACTIVITY_SAVE_ERROR(41023, "保存优惠券活动失败"),
|
||||
COUPON_ACTIVITY_MAX_NUM(41024, "优惠券活动赠券数量最多为3"),
|
||||
|
||||
COUPON_DO_NOT_RECEIVER(41030, "当前优惠券不允许主动领取"),
|
||||
|
||||
/**
|
||||
* 拼团
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package cn.lili.common.event;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* 事务提交后发生mq事件
|
||||
*
|
||||
* @author paulG
|
||||
* @since 2022/1/19
|
||||
**/
|
||||
public class TransactionCommitSendMQEvent extends ApplicationEvent {
|
||||
|
||||
private static final long serialVersionUID = 5885956821347953071L;
|
||||
|
||||
|
||||
@Getter
|
||||
private final String topic;
|
||||
|
||||
@Getter
|
||||
private final String tag;
|
||||
|
||||
@Getter
|
||||
private final Object message;
|
||||
|
||||
public TransactionCommitSendMQEvent(Object source, String topic, String tag, Object message) {
|
||||
super(source);
|
||||
this.topic = topic;
|
||||
this.tag = tag;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.lili.common.exception;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 如需异常重试,则抛出此异常
|
||||
*
|
||||
* @author paulG
|
||||
* @since 2022/4/26
|
||||
**/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class RetryException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 7886918292771470846L;
|
||||
|
||||
public RetryException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.lili.common.listener;
|
||||
|
||||
import cn.lili.common.event.TransactionCommitSendMQEvent;
|
||||
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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
|
||||
@Slf4j
|
||||
public class TransactionCommitSendMQListener {
|
||||
|
||||
/**
|
||||
* rocketMq
|
||||
*/
|
||||
@Autowired
|
||||
private RocketMQTemplate rocketMQTemplate;
|
||||
|
||||
|
||||
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
|
||||
public void send(TransactionCommitSendMQEvent event) {
|
||||
log.info("事务提交,发送mq信息!{}", event);
|
||||
String destination = event.getTopic() + ":" + event.getTag();
|
||||
//发送订单变更mq消息
|
||||
rocketMQTemplate.asyncSend(destination, event.getMessage(), RocketmqSendCallbackBuilder.commonCallback());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package cn.lili.common.utils;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* 通用工具
|
||||
@@ -9,6 +9,8 @@ import java.util.UUID;
|
||||
*/
|
||||
public class CommonUtil {
|
||||
|
||||
public static final String BASE_NUMBER = "0123456789";
|
||||
|
||||
/**
|
||||
* 以UUID重命名
|
||||
* @param fileName 文件名称
|
||||
@@ -24,12 +26,12 @@ public class CommonUtil {
|
||||
* 随机6位数生成
|
||||
*/
|
||||
public static String getRandomNum() {
|
||||
|
||||
Random random = new Random();
|
||||
int num = random.nextInt(999999);
|
||||
//不足六位前面补0
|
||||
String str = String.format("%06d", num);
|
||||
return str;
|
||||
StringBuilder sb = new StringBuilder(6);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int num = ThreadLocalRandom.current().nextInt(BASE_NUMBER.length());
|
||||
sb.append(BASE_NUMBER.charAt(num));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,23 @@ public class DateUtil {
|
||||
public static final String FULL_DATE = "yyyyMMddHHmmss";
|
||||
|
||||
|
||||
/**
|
||||
* 当天的开始时间
|
||||
*
|
||||
* @return 今天开始时间
|
||||
*/
|
||||
public static Long getDayOfStart() {
|
||||
return DateUtil.getDateline()/(60*24*60);
|
||||
}
|
||||
/**
|
||||
* 指定日的开始时间
|
||||
*
|
||||
* @return 指定日时间
|
||||
*/
|
||||
public static Long getDayOfStart(Date date) {
|
||||
return date.getTime()/(60*24*60);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当天的开始时间
|
||||
*
|
||||
|
||||
@@ -147,6 +147,20 @@ public class StringUtils extends StrUtil {
|
||||
return str.concat(appendStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 切割字符串
|
||||
*
|
||||
* @param str 字符串
|
||||
* @param length 长度
|
||||
* @return 处理后的字符串
|
||||
*/
|
||||
public static String sub(String str, Integer length) {
|
||||
if (str.length() < length) {
|
||||
return str;
|
||||
}
|
||||
return str.substring(0, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤特殊字符串
|
||||
*
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* @author paulG
|
||||
@@ -124,7 +123,7 @@ public abstract class BaseElasticsearchService {
|
||||
" \"type\": \"keyword\"\n" +
|
||||
" },\n" +
|
||||
" \"type\": {\n" +
|
||||
" \"type\": \"long\"\n" +
|
||||
" \"type\": \"integer\"\n" +
|
||||
" },\n" +
|
||||
" \"value\": {\n" +
|
||||
" \"type\": \"keyword\"\n" +
|
||||
@@ -165,14 +164,8 @@ public abstract class BaseElasticsearchService {
|
||||
" \"type\": \"long\"\n" +
|
||||
" },\n" +
|
||||
" \"releaseTime\": {\n" +
|
||||
" \"type\": \"text\",\n" +
|
||||
" \"fielddata\": true, \n" +
|
||||
" \"fields\": {\n" +
|
||||
" \"keyword\": {\n" +
|
||||
" \"type\": \"keyword\",\n" +
|
||||
" \"ignore_above\": 256\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" \"type\": \"date\",\n" +
|
||||
" \"format\": \"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis\"\n" +
|
||||
" },\n" +
|
||||
" \"categoryPath\": {\n" +
|
||||
" \"type\": \"text\",\n" +
|
||||
@@ -348,20 +341,20 @@ public abstract class BaseElasticsearchService {
|
||||
|
||||
PutMappingRequest request = new PutMappingRequest(index).source(source, XContentType.JSON);
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
AtomicReference<AcknowledgedResponse> response = new AtomicReference<>();
|
||||
client.indices().putMappingAsync(
|
||||
request,
|
||||
RequestOptions.DEFAULT,
|
||||
new ActionListener<AcknowledgedResponse>() {
|
||||
@Override
|
||||
public void onResponse(AcknowledgedResponse r) {
|
||||
response.set(r);
|
||||
latch.countDown();
|
||||
log.info("创建索引mapping成功:{}", r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
latch.countDown();
|
||||
log.error("创建索引mapping失败", e);
|
||||
}
|
||||
});
|
||||
latch.await(10, TimeUnit.SECONDS);
|
||||
|
||||
@@ -16,7 +16,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.io.IOException;
|
||||
@@ -69,11 +68,6 @@ public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
|
||||
return client;
|
||||
}
|
||||
|
||||
@Bean("elasticsearchRestTemplate")
|
||||
public ElasticsearchRestTemplate elasticsearchRestTemplate() {
|
||||
return new ElasticsearchRestTemplate(this.client);
|
||||
}
|
||||
|
||||
private HttpHost[] getHttpHosts() {
|
||||
List<String> clusterNodes = elasticsearchProperties.getClusterNodes();
|
||||
HttpHost[] httpHosts = new HttpHost[clusterNodes.size()];
|
||||
|
||||
@@ -112,4 +112,11 @@ public interface ConnectService extends IService<Connect> {
|
||||
* @return
|
||||
*/
|
||||
Connect queryConnect(ConnectQueryDTO connectQueryDTO);
|
||||
|
||||
/**
|
||||
* 根据会员id删除记录
|
||||
*
|
||||
* @param userId 会员id
|
||||
*/
|
||||
void deleteByMemberId(String userId);
|
||||
}
|
||||
@@ -8,7 +8,9 @@ import cn.lili.cache.CachePrefix;
|
||||
import cn.lili.common.context.ThreadContextHolder;
|
||||
import cn.lili.common.enums.ClientTypeEnum;
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.event.TransactionCommitSendMQEvent;
|
||||
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.security.token.Token;
|
||||
@@ -29,11 +31,13 @@ import cn.lili.modules.system.entity.dto.connect.WechatConnectSetting;
|
||||
import cn.lili.modules.system.entity.dto.connect.dto.WechatConnectSettingItem;
|
||||
import cn.lili.modules.system.entity.enums.SettingEnum;
|
||||
import cn.lili.modules.system.service.SettingService;
|
||||
import cn.lili.rocketmq.tags.MemberTagsEnum;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -66,6 +70,14 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
|
||||
private MemberTokenGenerate memberTokenGenerate;
|
||||
@Autowired
|
||||
private Cache cache;
|
||||
/**
|
||||
* RocketMQ 配置
|
||||
*/
|
||||
@Autowired
|
||||
private RocketmqCustomProperties rocketmqCustomProperties;
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@@ -89,6 +101,7 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
|
||||
}
|
||||
return memberTokenGenerate.createToken(member, longTerm);
|
||||
} catch (NoPermissionException e) {
|
||||
log.error("联合登陆失败:", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@@ -121,7 +134,7 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
|
||||
|
||||
@Override
|
||||
public void bind(String unionId, String type) {
|
||||
AuthUser authUser = UserContext.getCurrentUser();
|
||||
AuthUser authUser = Objects.requireNonNull(UserContext.getCurrentUser());
|
||||
Connect connect = new Connect(authUser.getId(), unionId, type);
|
||||
this.save(connect);
|
||||
}
|
||||
@@ -160,6 +173,7 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Token miniProgramAutoLogin(WechatMPLoginParams params) {
|
||||
|
||||
Object cacheData = cache.get(CachePrefix.WECHAT_SESSION_PARAMS.getPrefix() + params.getUuid());
|
||||
@@ -186,8 +200,8 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
|
||||
/**
|
||||
* 通过微信返回等code 获取openid 等信息
|
||||
*
|
||||
* @param code
|
||||
* @return
|
||||
* @param code 微信code
|
||||
* @return 微信返回的信息
|
||||
*/
|
||||
public JSONObject getConnect(String code) {
|
||||
WechatConnectSettingItem setting = getWechatMPSetting();
|
||||
@@ -208,11 +222,12 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
|
||||
* @param params 微信小程序自动登录参数
|
||||
* @param openId 微信openid
|
||||
* @param unionId 微信unionid
|
||||
* @return
|
||||
* @return token
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Token phoneMpBindAndLogin(String sessionKey, WechatMPLoginParams params, String openId, String unionId) {
|
||||
String encryptedData = params.getEncryptedData(), iv = params.getIv();
|
||||
String encryptedData = params.getEncryptedData();
|
||||
String iv = params.getIv();
|
||||
JSONObject userInfo = this.getUserInfo(encryptedData, sessionKey, iv);
|
||||
log.info("联合登陆返回:{}", userInfo.toString());
|
||||
String phone = (String) userInfo.get("purePhoneNumber");
|
||||
@@ -232,6 +247,8 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
|
||||
memberService.save(newMember);
|
||||
newMember = memberService.findByUsername(newMember.getUsername());
|
||||
bindMpMember(openId, unionId, newMember);
|
||||
// 发送会员注册信息
|
||||
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("new member register", rocketmqCustomProperties.getMemberTopic(), MemberTagsEnum.MEMBER_REGISTER.name(), newMember));
|
||||
return memberTokenGenerate.createToken(newMember, true);
|
||||
}
|
||||
|
||||
@@ -245,6 +262,13 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
|
||||
return this.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByMemberId(String userId) {
|
||||
LambdaQueryWrapper<Connect> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(Connect::getUserId, userId);
|
||||
this.remove(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 会员绑定 绑定微信小程序
|
||||
* <p>
|
||||
@@ -252,9 +276,9 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
|
||||
* 这样,微信小程序注册之后,其他app 公众号页面,都可以实现绑定自动登录功能
|
||||
* </p>
|
||||
*
|
||||
* @param openId
|
||||
* @param unionId
|
||||
* @param member
|
||||
* @param openId 微信openid
|
||||
* @param unionId 微信unionid
|
||||
* @param member 会员
|
||||
*/
|
||||
private void bindMpMember(String openId, String unionId, Member member) {
|
||||
|
||||
@@ -265,7 +289,7 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
|
||||
lambdaQueryWrapper.eq(Connect::getUnionId, unionId);
|
||||
lambdaQueryWrapper.eq(Connect::getUnionType, ConnectEnum.WECHAT.name());
|
||||
List<Connect> connects = this.list(lambdaQueryWrapper);
|
||||
if (connects.size() == 0) {
|
||||
if (connects.isEmpty()) {
|
||||
Connect connect = new Connect();
|
||||
connect.setUnionId(unionId);
|
||||
connect.setUserId(member.getId());
|
||||
@@ -274,7 +298,7 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
|
||||
}
|
||||
}//如果openid 不为空 则为账号绑定openid
|
||||
if (CharSequenceUtil.isNotEmpty(openId)) {
|
||||
LambdaQueryWrapper<Connect> lambdaQueryWrapper = new LambdaQueryWrapper();
|
||||
LambdaQueryWrapper<Connect> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.eq(Connect::getUnionId, openId);
|
||||
lambdaQueryWrapper.eq(Connect::getUnionType, ConnectEnum.WECHAT_MP_OPEN_ID.name());
|
||||
List<Connect> connects = this.list(lambdaQueryWrapper);
|
||||
|
||||
@@ -50,6 +50,9 @@ public class DistributionOrder extends BaseIdEntity {
|
||||
private String distributionId;
|
||||
@ApiModelProperty(value = "分销员名称")
|
||||
private String distributionName;
|
||||
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@ApiModelProperty(value = "解冻日期")
|
||||
private Date settleCycle;
|
||||
@ApiModelProperty(value = "提成金额")
|
||||
|
||||
@@ -73,6 +73,7 @@ public class DistributionCashServiceImpl extends ServiceImpl<DistributionCashMap
|
||||
}
|
||||
//将提现金额存入冻结金额,扣减可提现金额
|
||||
distribution.setCanRebate(CurrencyUtil.sub(distribution.getCanRebate(), applyMoney));
|
||||
distribution.setCommissionFrozen(CurrencyUtil.add(distribution.getCommissionFrozen(), applyMoney));
|
||||
distributionService.updateById(distribution);
|
||||
//提现申请记录
|
||||
DistributionCash distributionCash = new DistributionCash("D" + SnowFlake.getId(), distribution.getId(), applyMoney, distribution.getMemberName());
|
||||
|
||||
@@ -94,6 +94,9 @@ public class DistributionOrderServiceImpl extends ServiceImpl<DistributionOrderM
|
||||
//循环店铺流水记录判断是否包含分销商品
|
||||
//包含分销商品则进行记录分销订单、计算分销总额
|
||||
for (StoreFlow storeFlow : storeFlowList) {
|
||||
if (storeFlow.getDistributionRebate() == null || storeFlow.getDistributionRebate() == 0) {
|
||||
continue;
|
||||
}
|
||||
rebate = CurrencyUtil.add(rebate, storeFlow.getDistributionRebate());
|
||||
DistributionOrder distributionOrder = new DistributionOrder(storeFlow);
|
||||
distributionOrder.setDistributionId(order.getDistributionId());
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.lili.modules.file.entity.enums;
|
||||
|
||||
import com.aliyun.oss.OSS;
|
||||
|
||||
/**
|
||||
* OssEnum
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v1.0
|
||||
* 2022-06-06 11:23
|
||||
*/
|
||||
public enum OssEnum {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
ALI_OSS, MINIO;
|
||||
}
|
||||
@@ -1,16 +1,23 @@
|
||||
package cn.lili.modules.file.plugin;
|
||||
|
||||
import cn.lili.modules.file.entity.enums.OssEnum;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 文件管理插件
|
||||
* 文件插件接口
|
||||
*
|
||||
* @author Chopper
|
||||
*/
|
||||
public interface FileManagerPlugin {
|
||||
public interface FilePlugin {
|
||||
|
||||
|
||||
/**
|
||||
* 插件名称
|
||||
*/
|
||||
OssEnum pluginName();
|
||||
|
||||
/**
|
||||
* 文件路径上传
|
||||
*
|
||||
@@ -0,0 +1,59 @@
|
||||
package cn.lili.modules.file.plugin;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.modules.file.entity.enums.OssEnum;
|
||||
import cn.lili.modules.file.plugin.impl.AliFilePlugin;
|
||||
import cn.lili.modules.file.plugin.impl.MinioFilePlugin;
|
||||
import cn.lili.modules.system.entity.dos.Setting;
|
||||
import cn.lili.modules.system.entity.dto.OssSetting;
|
||||
import cn.lili.modules.system.entity.enums.SettingEnum;
|
||||
import cn.lili.modules.system.service.SettingService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 文件服务抽象工厂 直接返回操作类
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v1.0
|
||||
* 2022-06-06 11:35
|
||||
*/
|
||||
@Component
|
||||
public class FilePluginFactory {
|
||||
|
||||
|
||||
@Autowired
|
||||
private SettingService settingService;
|
||||
|
||||
|
||||
/**
|
||||
* 获取oss client
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public FilePlugin filePlugin() {
|
||||
|
||||
OssSetting ossSetting = null;
|
||||
try {
|
||||
Setting setting = settingService.get(SettingEnum.OSS_SETTING.name());
|
||||
|
||||
ossSetting = JSONUtil.toBean(setting.getSettingValue(), OssSetting.class);
|
||||
|
||||
|
||||
switch (OssEnum.valueOf(ossSetting.getType())) {
|
||||
|
||||
case MINIO:
|
||||
return new MinioFilePlugin(ossSetting);
|
||||
case ALI_OSS:
|
||||
return new AliFilePlugin(ossSetting);
|
||||
default:
|
||||
throw new ServiceException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,23 +1,17 @@
|
||||
package cn.lili.modules.file.plugin.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.modules.file.plugin.FileManagerPlugin;
|
||||
import cn.lili.modules.system.entity.dos.Setting;
|
||||
import cn.lili.modules.file.entity.enums.OssEnum;
|
||||
import cn.lili.modules.file.plugin.FilePlugin;
|
||||
import cn.lili.modules.system.entity.dto.OssSetting;
|
||||
import cn.lili.modules.system.entity.enums.SettingEnum;
|
||||
import cn.lili.modules.system.service.SettingService;
|
||||
import com.aliyun.oss.ClientException;
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.aliyun.oss.OSSException;
|
||||
import com.aliyun.oss.model.DeleteObjectsRequest;
|
||||
import com.aliyun.oss.model.ObjectMetadata;
|
||||
import com.google.gson.Gson;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
@@ -29,28 +23,19 @@ import java.util.List;
|
||||
* @author Chopper
|
||||
*/
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AliFileManagerPlugin implements FileManagerPlugin {
|
||||
public class AliFilePlugin implements FilePlugin {
|
||||
|
||||
@Autowired
|
||||
private SettingService settingService;
|
||||
private OssSetting ossSetting;
|
||||
|
||||
/**
|
||||
* 下一个初始化配置参数的时间
|
||||
* 这里为了防止多次调用redis,减少与redis的交互时间
|
||||
*/
|
||||
private static Long nextInitSetting;
|
||||
public AliFilePlugin(OssSetting ossSetting) {
|
||||
this.ossSetting = ossSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂时设定3分账请求一次设置
|
||||
*/
|
||||
private static final Long INTERVAL = 60 * 3 * 1000L;
|
||||
|
||||
/**
|
||||
* 静态设置,最快三分钟更新一次
|
||||
*/
|
||||
private static OssSetting ossSetting;
|
||||
@Override
|
||||
public OssEnum pluginName() {
|
||||
return OssEnum.ALI_OSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取oss client
|
||||
@@ -58,32 +43,12 @@ public class AliFileManagerPlugin implements FileManagerPlugin {
|
||||
* @return
|
||||
*/
|
||||
private OSS getOssClient() {
|
||||
OssSetting ossSetting = getSetting();
|
||||
|
||||
return new OSSClientBuilder().build(
|
||||
ossSetting.getEndPoint(),
|
||||
ossSetting.getAccessKeyId(),
|
||||
ossSetting.getAccessKeySecret());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private OssSetting getSetting() {
|
||||
//如果没有配置,或者没有下次刷新时间,或者下次刷新时间小于当前时间,则从redis 更新一次
|
||||
if (ossSetting == null || nextInitSetting == null || nextInitSetting < System.currentTimeMillis()) {
|
||||
Setting setting = settingService.get(SettingEnum.OSS_SETTING.name());
|
||||
if (setting == null || StrUtil.isBlank(setting.getSettingValue())) {
|
||||
throw new ServiceException(ResultCode.OSS_NOT_EXIST);
|
||||
}
|
||||
nextInitSetting = System.currentTimeMillis() + INTERVAL;
|
||||
ossSetting = new Gson().fromJson(setting.getSettingValue(), OssSetting.class);
|
||||
return ossSetting;
|
||||
}
|
||||
return ossSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置前缀
|
||||
@@ -91,7 +56,6 @@ public class AliFileManagerPlugin implements FileManagerPlugin {
|
||||
* @return
|
||||
*/
|
||||
private String getUrlPrefix() {
|
||||
OssSetting ossSetting = getSetting();
|
||||
return "https://" + ossSetting.getBucketName() + "." + ossSetting.getEndPoint() + "/";
|
||||
}
|
||||
|
||||
@@ -130,7 +94,7 @@ public class AliFileManagerPlugin implements FileManagerPlugin {
|
||||
try {
|
||||
ObjectMetadata meta = new ObjectMetadata();
|
||||
meta.setContentType("image/jpg");
|
||||
ossClient.putObject(getSetting().getBucketName(), key, inputStream, meta);
|
||||
ossClient.putObject(ossSetting.getBucketName(), key, inputStream, meta);
|
||||
} catch (OSSException oe) {
|
||||
log.error("Caught an OSSException, which means your request made it to OSS, "
|
||||
+ "but was rejected with an error response for some reason.");
|
||||
@@ -161,7 +125,7 @@ public class AliFileManagerPlugin implements FileManagerPlugin {
|
||||
|
||||
try {
|
||||
ossClient.deleteObjects(
|
||||
new DeleteObjectsRequest(getSetting().getBucketName()).withKeys(key));
|
||||
new DeleteObjectsRequest(ossSetting.getBucketName()).withKeys(key));
|
||||
} catch (OSSException oe) {
|
||||
log.error("Caught an OSSException, which means your request made it to OSS, "
|
||||
+ "but was rejected with an error response for some reason.");
|
||||
@@ -0,0 +1,165 @@
|
||||
package cn.lili.modules.file.plugin.impl;
|
||||
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.modules.file.entity.enums.OssEnum;
|
||||
import cn.lili.modules.file.plugin.FilePlugin;
|
||||
import cn.lili.modules.system.entity.dto.OssSetting;
|
||||
import io.minio.*;
|
||||
import io.minio.errors.ErrorResponseException;
|
||||
import io.minio.messages.DeleteObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* MINIO文件插件
|
||||
*
|
||||
* @author liushuai(liushuai711 @ gmail.com)
|
||||
* @version v4.0
|
||||
* @Description:
|
||||
* @since 2022/6/6 17:45
|
||||
*/
|
||||
@Slf4j
|
||||
public class MinioFilePlugin implements FilePlugin {
|
||||
|
||||
private OssSetting ossSetting;
|
||||
|
||||
public MinioFilePlugin(OssSetting ossSetting) {
|
||||
this.ossSetting = ossSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* 桶占位符
|
||||
*/
|
||||
private static final String BUCKET_PARAM = "${bucket}";
|
||||
/**
|
||||
* bucket权限-只读
|
||||
*/
|
||||
private static final String READ_ONLY = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetObject\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";
|
||||
/**
|
||||
* bucket权限-只读
|
||||
*/
|
||||
private static final String WRITE_ONLY = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";
|
||||
/**
|
||||
* bucket权限-读写
|
||||
*/
|
||||
private static final String READ_WRITE = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";
|
||||
|
||||
|
||||
private MinioClient minioClient;
|
||||
|
||||
|
||||
@Override
|
||||
public OssEnum pluginName() {
|
||||
return OssEnum.MINIO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pathUpload(String filePath, String key) {
|
||||
try {
|
||||
return this.inputStreamUpload(new FileInputStream(filePath), key);
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException(ResultCode.OSS_DELETE_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String inputStreamUpload(InputStream inputStream, String key) {
|
||||
String bucket = "";
|
||||
try {
|
||||
MinioClient client = getOssClient();
|
||||
bucket = ossSetting.getM_bucketName();
|
||||
PutObjectArgs putObjectArgs = PutObjectArgs.builder()
|
||||
.bucket(bucket).stream(inputStream, inputStream.available(), 5 * 1024 * 1024)
|
||||
.object(key)
|
||||
.contentType("image/png" )
|
||||
.build();
|
||||
client.putObject(putObjectArgs);
|
||||
} catch (Exception e) {
|
||||
log.error("上传失败2,", e);
|
||||
throw new ServiceException(ResultCode.OSS_DELETE_ERROR, e.getMessage());
|
||||
}
|
||||
//拼接出可访问的url地址
|
||||
return ossSetting.getM_frontUrl() + "/" + bucket + "/" + key;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void deleteFile(List<String> key) {
|
||||
if (key == null || key.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
MinioClient ossClient = getOssClient();
|
||||
List<DeleteObject> objectList = key.stream().map(DeleteObject::new).collect(Collectors.toList());
|
||||
ossClient.removeObjects(RemoveObjectsArgs.builder().objects(objectList).bucket(ossSetting.getM_bucketName()).build());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取oss client
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private MinioClient getOssClient() {
|
||||
if (minioClient != null) {
|
||||
return this.minioClient;
|
||||
}
|
||||
synchronized (this) {
|
||||
if (minioClient == null) {
|
||||
//创建客户端
|
||||
this.minioClient = MinioClient.builder()
|
||||
.endpoint(ossSetting.getM_endpoint())
|
||||
.credentials(ossSetting.getM_accessKey(), ossSetting.getM_secretKey())
|
||||
.build();
|
||||
try {
|
||||
//查看对应的bucket是否已经存在,不存在则创建
|
||||
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(ossSetting.getM_bucketName()).build())) {
|
||||
//创建bucket
|
||||
MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(ossSetting.getM_bucketName()).build();
|
||||
this.minioClient.makeBucket(makeBucketArgs);
|
||||
setBucketPolicy(this.minioClient, ossSetting.getM_bucketName(), "read-write" );
|
||||
log.info("创建minio桶成功{}", ossSetting.getM_bucketName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
//晴空配置
|
||||
minioClient = null;
|
||||
log.error("创建[{}]bucket失败", ossSetting.getM_bucketName());
|
||||
throw new ServiceException(ResultCode.OSS_DELETE_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
return minioClient;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新桶权限策略
|
||||
*
|
||||
* @param bucket 桶
|
||||
* @param policy 权限
|
||||
*/
|
||||
public static void setBucketPolicy(MinioClient client, String bucket, String policy) throws Exception {
|
||||
switch (policy) {
|
||||
case "read-only":
|
||||
client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).config(READ_ONLY.replace(BUCKET_PARAM, bucket)).build());
|
||||
break;
|
||||
case "write-only":
|
||||
client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).config(WRITE_ONLY.replace(BUCKET_PARAM, bucket)).build());
|
||||
break;
|
||||
case "read-write":
|
||||
client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).region("public" ).config(READ_WRITE.replace(BUCKET_PARAM, bucket)).build());
|
||||
break;
|
||||
case "none":
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -10,7 +10,8 @@ import cn.lili.common.vo.SearchVO;
|
||||
import cn.lili.modules.file.entity.File;
|
||||
import cn.lili.modules.file.entity.dto.FileOwnerDTO;
|
||||
import cn.lili.modules.file.mapper.FileMapper;
|
||||
import cn.lili.modules.file.plugin.FileManagerPlugin;
|
||||
import cn.lili.modules.file.plugin.FilePlugin;
|
||||
import cn.lili.modules.file.plugin.FilePluginFactory;
|
||||
import cn.lili.modules.file.service.FileService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
@@ -31,7 +32,7 @@ import java.util.List;
|
||||
public class FileServiceImpl extends ServiceImpl<FileMapper, File> implements FileService {
|
||||
|
||||
@Autowired
|
||||
private FileManagerPlugin fileManagerPlugin;
|
||||
private FilePluginFactory filePluginFactory;
|
||||
|
||||
@Override
|
||||
public void batchDelete(List<String> ids) {
|
||||
@@ -42,7 +43,7 @@ public class FileServiceImpl extends ServiceImpl<FileMapper, File> implements Fi
|
||||
List<File> files = this.list(queryWrapper);
|
||||
List<String> keys = new ArrayList<>();
|
||||
files.forEach(item -> keys.add(item.getFileKey()));
|
||||
fileManagerPlugin.deleteFile(keys);
|
||||
filePluginFactory.filePlugin().deleteFile(keys);
|
||||
this.remove(queryWrapper);
|
||||
}
|
||||
|
||||
@@ -68,7 +69,7 @@ public class FileServiceImpl extends ServiceImpl<FileMapper, File> implements Fi
|
||||
List<File> files = this.list(queryWrapper);
|
||||
List<String> keys = new ArrayList<>();
|
||||
files.forEach(item -> keys.add(item.getFileKey()));
|
||||
fileManagerPlugin.deleteFile(keys);
|
||||
filePluginFactory.filePlugin().deleteFile(keys);
|
||||
this.remove(queryWrapper);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
|
||||
@@ -114,6 +113,9 @@ public class DraftGoods extends BaseEntity {
|
||||
@ApiModelProperty(value = "是否为推荐商品")
|
||||
private boolean recommend;
|
||||
|
||||
/**
|
||||
* @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum
|
||||
*/
|
||||
@ApiModelProperty(value = "销售模式")
|
||||
private String salesModel;
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsOperationFuLuDTO;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsTypeEnum;
|
||||
import cn.lili.mybatis.BaseEntity;
|
||||
@@ -108,6 +109,9 @@ public class Goods extends BaseEntity {
|
||||
@ApiModelProperty(value = "运费模板id")
|
||||
private String templateId;
|
||||
|
||||
/**
|
||||
* @see GoodsAuthEnum
|
||||
*/
|
||||
@ApiModelProperty(value = "审核状态")
|
||||
private String authFlag;
|
||||
|
||||
@@ -130,6 +134,9 @@ public class Goods extends BaseEntity {
|
||||
@ApiModelProperty(value = "是否为推荐商品", required = true)
|
||||
private Boolean recommend;
|
||||
|
||||
/**
|
||||
* @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum
|
||||
*/
|
||||
@ApiModelProperty(value = "销售模式", required = true)
|
||||
private String salesModel;
|
||||
|
||||
@@ -144,83 +151,15 @@ public class Goods extends BaseEntity {
|
||||
@JsonIgnore
|
||||
private String params;
|
||||
|
||||
//福禄所需参数
|
||||
/**
|
||||
* 商品编号
|
||||
*/
|
||||
@Length(max = 30, message = "商品规格编号太长,不能超过30个字符")
|
||||
@ApiModelProperty(value = "商品编号")
|
||||
private String sn;
|
||||
|
||||
/**
|
||||
* 重量
|
||||
*/
|
||||
@ApiModelProperty(value = "重量")
|
||||
@Max(value = 99999999, message = "重量不能超过99999999")
|
||||
private Double weight;
|
||||
|
||||
public Goods() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 福禄
|
||||
* @param goodsOperationDTO
|
||||
*/
|
||||
public Goods(GoodsOperationFuLuDTO goodsOperationDTO) {
|
||||
this.goodsName = goodsOperationDTO.getGoodsName();
|
||||
this.categoryPath = goodsOperationDTO.getCategoryPath();
|
||||
this.storeCategoryPath = goodsOperationDTO.getStoreCategoryPath();
|
||||
this.brandId = goodsOperationDTO.getBrandId();
|
||||
this.sn = goodsOperationDTO.getSn();
|
||||
this.price = goodsOperationDTO.getPrice();
|
||||
this.weight = goodsOperationDTO.getWeight();
|
||||
this.templateId = goodsOperationDTO.getTemplateId();
|
||||
this.recommend = goodsOperationDTO.getRecommend();
|
||||
this.sellingPoint = goodsOperationDTO.getSellingPoint();
|
||||
this.salesModel = goodsOperationDTO.getSalesModel();
|
||||
this.goodsUnit = goodsOperationDTO.getGoodsUnit();
|
||||
this.intro = goodsOperationDTO.getIntro();
|
||||
this.mobileIntro = goodsOperationDTO.getMobileIntro();
|
||||
this.goodsVideo = goodsOperationDTO.getGoodsVideo();
|
||||
this.price = goodsOperationDTO.getPrice();
|
||||
if (goodsOperationDTO.getGoodsParamsDTOList() != null && goodsOperationDTO.getGoodsParamsDTOList().isEmpty()) {
|
||||
this.params = JSONUtil.toJsonStr(goodsOperationDTO.getGoodsParamsDTOList());
|
||||
}
|
||||
//如果立即上架则
|
||||
this.marketEnable = Boolean.TRUE.equals(goodsOperationDTO.getRelease()) ? GoodsStatusEnum.UPPER.name() : GoodsStatusEnum.DOWN.name();
|
||||
this.goodsType = goodsOperationDTO.getGoodsType();
|
||||
this.grade = 100D;
|
||||
|
||||
//循环sku,判定sku是否有效
|
||||
for (Map<String, Object> sku : goodsOperationDTO.getSkuList()) {
|
||||
//判定参数不能为空
|
||||
if (!sku.containsKey("sn") || sku.get("sn") == null) {
|
||||
throw new ServiceException(ResultCode.GOODS_SKU_SN_ERROR);
|
||||
}
|
||||
if (!sku.containsKey("price") || StringUtil.isEmpty(sku.get("price").toString()) || Convert.toDouble(sku.get("price")) <= 0) {
|
||||
throw new ServiceException(ResultCode.GOODS_SKU_PRICE_ERROR);
|
||||
}
|
||||
if (!sku.containsKey("cost") || StringUtil.isEmpty(sku.get("cost").toString()) || Convert.toDouble(sku.get("cost")) <= 0) {
|
||||
throw new ServiceException(ResultCode.GOODS_SKU_COST_ERROR);
|
||||
}
|
||||
//虚拟商品没有重量字段
|
||||
if (this.goodsType.equals(GoodsTypeEnum.PHYSICAL_GOODS.name()) && (!sku.containsKey("weight") || sku.containsKey("weight") && (StringUtil.isEmpty(sku.get("weight").toString()) || Convert.toDouble(sku.get("weight").toString()) < 0))) {
|
||||
throw new ServiceException(ResultCode.GOODS_SKU_WEIGHT_ERROR);
|
||||
}
|
||||
if (!sku.containsKey("quantity") || StringUtil.isEmpty(sku.get("quantity").toString()) || Convert.toInt(sku.get("quantity").toString()) < 0) {
|
||||
throw new ServiceException(ResultCode.GOODS_SKU_QUANTITY_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Goods(GoodsOperationDTO goodsOperationDTO) {
|
||||
this.goodsName = goodsOperationDTO.getGoodsName();
|
||||
this.categoryPath = goodsOperationDTO.getCategoryPath();
|
||||
this.storeCategoryPath = goodsOperationDTO.getStoreCategoryPath();
|
||||
this.brandId = goodsOperationDTO.getBrandId();
|
||||
this.price = goodsOperationDTO.getPrice();
|
||||
this.templateId = goodsOperationDTO.getTemplateId();
|
||||
this.recommend = goodsOperationDTO.getRecommend();
|
||||
this.sellingPoint = goodsOperationDTO.getSellingPoint();
|
||||
@@ -244,10 +183,10 @@ public class Goods extends BaseEntity {
|
||||
if (!sku.containsKey("sn") || sku.get("sn") == null) {
|
||||
throw new ServiceException(ResultCode.GOODS_SKU_SN_ERROR);
|
||||
}
|
||||
if (!sku.containsKey("price") || StringUtil.isEmpty(sku.get("price").toString()) || Convert.toDouble(sku.get("price")) <= 0) {
|
||||
if ((!sku.containsKey("price") || StringUtil.isEmpty(sku.get("price").toString()) || Convert.toDouble(sku.get("price")) <= 0) && !goodsOperationDTO.getSalesModel().equals(GoodsSalesModeEnum.WHOLESALE.name())) {
|
||||
throw new ServiceException(ResultCode.GOODS_SKU_PRICE_ERROR);
|
||||
}
|
||||
if (!sku.containsKey("cost") || StringUtil.isEmpty(sku.get("cost").toString()) || Convert.toDouble(sku.get("cost")) <= 0) {
|
||||
if ((!sku.containsKey("cost") || StringUtil.isEmpty(sku.get("cost").toString()) || Convert.toDouble(sku.get("cost")) <= 0) && !goodsOperationDTO.getSalesModel().equals(GoodsSalesModeEnum.WHOLESALE.name())) {
|
||||
throw new ServiceException(ResultCode.GOODS_SKU_COST_ERROR);
|
||||
}
|
||||
//虚拟商品没有重量字段
|
||||
@@ -275,4 +214,4 @@ public class Goods extends BaseEntity {
|
||||
return mobileIntro;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
@@ -24,6 +25,7 @@ import java.util.Date;
|
||||
@Data
|
||||
@TableName("li_goods_sku")
|
||||
@ApiModel(value = "商品sku对象")
|
||||
@NoArgsConstructor
|
||||
public class GoodsSku extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 4865908658161118934L;
|
||||
@@ -150,6 +152,9 @@ public class GoodsSku extends BaseEntity {
|
||||
@ApiModelProperty(value = "是否为推荐商品", required = true)
|
||||
private Boolean recommend;
|
||||
|
||||
/**
|
||||
* @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum
|
||||
*/
|
||||
@ApiModelProperty(value = "销售模式", required = true)
|
||||
private String salesModel;
|
||||
/**
|
||||
@@ -166,11 +171,43 @@ public class GoodsSku extends BaseEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getUpdateTime() {
|
||||
if (super.getUpdateTime() == null) {
|
||||
public Date getCreateTime() {
|
||||
if (super.getCreateTime() == null) {
|
||||
return new Date(1593571928);
|
||||
} else {
|
||||
return super.getUpdateTime();
|
||||
return super.getCreateTime();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置规格商品的基本商品信息
|
||||
*
|
||||
* @param goods 基本商品信息
|
||||
*/
|
||||
public GoodsSku(Goods goods) {
|
||||
//商品基本信息
|
||||
this.goodsId = goods.getId();
|
||||
this.goodsName = goods.getGoodsName();
|
||||
this.goodsType = goods.getGoodsType();
|
||||
|
||||
this.selfOperated = goods.getSelfOperated();
|
||||
this.sellingPoint = goods.getSellingPoint();
|
||||
this.categoryPath = goods.getCategoryPath();
|
||||
this.brandId = goods.getBrandId();
|
||||
this.marketEnable = goods.getMarketEnable();
|
||||
this.intro = goods.getIntro();
|
||||
this.mobileIntro = goods.getMobileIntro();
|
||||
this.goodsUnit = goods.getGoodsUnit();
|
||||
this.grade = 100D;
|
||||
//商品状态
|
||||
this.authFlag = goods.getAuthFlag();
|
||||
this.salesModel = goods.getSalesModel();
|
||||
//卖家信息
|
||||
this.storeId = goods.getStoreId();
|
||||
this.storeName = goods.getStoreName();
|
||||
this.storeCategoryPath = goods.getStoreCategoryPath();
|
||||
this.freightTemplateId = goods.getTemplateId();
|
||||
this.recommend = goods.getRecommend();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.lili.modules.goods.entity.dos;
|
||||
|
||||
import cn.lili.modules.goods.entity.enums.GoodsWordsTypeEnum;
|
||||
import cn.lili.mybatis.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
@@ -41,7 +42,7 @@ public class GoodsWords extends BaseEntity {
|
||||
private String abbreviate;
|
||||
|
||||
/**
|
||||
* 类型
|
||||
* @see GoodsWordsTypeEnum
|
||||
*/
|
||||
@ApiModelProperty(value = "类型")
|
||||
private String type;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.lili.modules.goods.entity.dos;
|
||||
|
||||
import cn.lili.modules.goods.entity.enums.StudioStatusEnum;
|
||||
import cn.lili.mybatis.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
@@ -88,6 +89,9 @@ public class Studio extends BaseEntity {
|
||||
@ApiModelProperty(value = "推荐直播间")
|
||||
private boolean recommend;
|
||||
|
||||
/**
|
||||
* @see StudioStatusEnum
|
||||
*/
|
||||
@ApiModelProperty(value = "直播间状态")
|
||||
private String status;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
|
||||
@@ -15,11 +16,14 @@ import lombok.NoArgsConstructor;
|
||||
* @since 2021/5/18 5:42 下午
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel(value = "直播间商品")
|
||||
@TableName("li_studio_commodity")
|
||||
@NoArgsConstructor
|
||||
public class StudioCommodity extends BaseIdEntity {
|
||||
|
||||
private static final long serialVersionUID = 8383627725577840261L;
|
||||
|
||||
@ApiModelProperty(value = "房间ID")
|
||||
private Integer roomId;
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.lili.modules.goods.entity.dos;
|
||||
|
||||
import cn.lili.mybatis.BaseIdEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author paulG
|
||||
* @since 2022/5/20
|
||||
**/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("li_wholesale")
|
||||
@ApiModel(value = "批发商品")
|
||||
public class Wholesale extends BaseIdEntity {
|
||||
|
||||
private static final long serialVersionUID = -6389806138583086068L;
|
||||
|
||||
@ApiModelProperty(value = "商品ID")
|
||||
private String goodsId;
|
||||
@ApiModelProperty(value = "SkuID")
|
||||
private String skuId;
|
||||
@ApiModelProperty(value = "数量")
|
||||
private Integer num;
|
||||
@ApiModelProperty(value = "金额")
|
||||
private Double price;
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 商品编辑DTO
|
||||
* 商品操作DTO
|
||||
*
|
||||
* @author pikachu
|
||||
* @since 2020-02-24 19:27:20
|
||||
@@ -77,13 +77,12 @@ public class GoodsOperationDTO implements Serializable {
|
||||
@Min(value = 0, message = "运费模板值不正确")
|
||||
private String templateId;
|
||||
|
||||
@ApiModelProperty(value = "sku列表")
|
||||
@Valid
|
||||
private List<Map<String, Object>> skuList;
|
||||
|
||||
@ApiModelProperty(value = "卖点")
|
||||
private String sellingPoint;
|
||||
|
||||
/**
|
||||
* @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum
|
||||
*/
|
||||
@ApiModelProperty(value = "销售模式", required = true)
|
||||
private String salesModel;
|
||||
|
||||
@@ -112,6 +111,17 @@ public class GoodsOperationDTO implements Serializable {
|
||||
@ApiModelProperty(value = "商品视频")
|
||||
private String goodsVideo;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "sku列表")
|
||||
@Valid
|
||||
private List<Map<String, Object>> skuList;
|
||||
|
||||
/**
|
||||
* 批发商品规则
|
||||
*/
|
||||
@ApiModelProperty(value = "批发商品规则")
|
||||
private List<WholesaleDTO> wholesaleList;
|
||||
|
||||
public String getGoodsName() {
|
||||
//对商品对名称做一个极限处理。这里没有用xss过滤是因为xss过滤为全局过滤,影响很大。
|
||||
// 业务中,全局代码中只有商品名称不能拥有英文逗号,是由于商品名称存在一个数据库联合查询,结果要根据逗号分组
|
||||
|
||||
@@ -77,6 +77,12 @@ public class GoodsSearchParams extends PageVO {
|
||||
@ApiModelProperty(value = "商品类型")
|
||||
private String goodsType;
|
||||
|
||||
/**
|
||||
* @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum
|
||||
*/
|
||||
@ApiModelProperty(value = "销售模式", required = true)
|
||||
private String salesModel;
|
||||
|
||||
public <T> QueryWrapper<T> queryWrapper() {
|
||||
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
|
||||
if (CharSequenceUtil.isNotEmpty(goodsId)) {
|
||||
@@ -121,6 +127,9 @@ public class GoodsSearchParams extends PageVO {
|
||||
if (CharSequenceUtil.isNotEmpty(goodsType)) {
|
||||
queryWrapper.eq("goods_type", goodsType);
|
||||
}
|
||||
if (CharSequenceUtil.isNotEmpty(salesModel)) {
|
||||
queryWrapper.eq("sales_model", salesModel);
|
||||
}
|
||||
|
||||
queryWrapper.eq("delete_flag", false);
|
||||
this.betweenWrapper(queryWrapper);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.lili.modules.goods.entity.dto;
|
||||
|
||||
import cn.lili.modules.goods.entity.dos.GoodsSku;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author paulG
|
||||
* @since 2022/6/13
|
||||
**/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class GoodsSkuDTO extends GoodsSku {
|
||||
|
||||
private static final long serialVersionUID = 6600436187015048097L;
|
||||
|
||||
@ApiModelProperty(value = "商品参数json")
|
||||
private String params;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.lili.modules.goods.entity.dto;
|
||||
|
||||
import cn.lili.modules.goods.entity.dos.Wholesale;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author paulG
|
||||
* @since 2022/5/25
|
||||
**/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class WholesaleDTO extends Wholesale {
|
||||
private static final long serialVersionUID = 853297561151783335L;
|
||||
|
||||
}
|
||||
@@ -1,19 +1,14 @@
|
||||
package cn.lili.modules.goods.entity.enums;
|
||||
|
||||
/**
|
||||
* 商品审核
|
||||
* 销售模式
|
||||
*
|
||||
* @author pikachu
|
||||
* @since 2020-02-26 23:24:13
|
||||
*/
|
||||
public enum GoodsSalesModeEnum {
|
||||
/**
|
||||
* 需要审核 并且待审核
|
||||
*/
|
||||
|
||||
RETAIL("零售"),
|
||||
/**
|
||||
* 审核通过
|
||||
*/
|
||||
WHOLESALE("批发");
|
||||
|
||||
private final String description;
|
||||
|
||||
@@ -5,6 +5,7 @@ import cn.lili.modules.goods.entity.dos.GoodsSku;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
@@ -16,6 +17,7 @@ import java.util.List;
|
||||
* @since 2020-02-26 23:24:13
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class GoodsSkuVO extends GoodsSku {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package cn.lili.modules.goods.entity.vos;
|
||||
|
||||
import cn.lili.modules.goods.entity.dos.Goods;
|
||||
import cn.lili.modules.goods.entity.dos.Wholesale;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -14,6 +16,7 @@ import java.util.List;
|
||||
* @since 2020-02-26 23:24:13
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class GoodsVO extends Goods {
|
||||
|
||||
private static final long serialVersionUID = 6377623919990713567L;
|
||||
@@ -29,4 +32,7 @@ public class GoodsVO extends Goods {
|
||||
|
||||
@ApiModelProperty(value = "sku列表")
|
||||
private List<GoodsSkuVO> skuList;
|
||||
|
||||
@ApiModelProperty(value = "批发商品消费规则列表")
|
||||
private List<Wholesale> wholesaleList;
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
package cn.lili.modules.goods.mapper;
|
||||
|
||||
import cn.lili.modules.goods.entity.dos.GoodsSku;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsSkuDTO;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import org.apache.ibatis.annotations.Insert;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
@@ -23,4 +29,89 @@ public interface GoodsSkuMapper extends BaseMapper<GoodsSku> {
|
||||
@Select("SELECT id FROM li_goods_sku WHERE goods_id = #{goodsId}")
|
||||
List<String> getGoodsSkuIdByGoodsId(String goodsId);
|
||||
|
||||
|
||||
@Insert("replace into li_goods_sku (\n" +
|
||||
"\tid,\n" +
|
||||
"\tgoods_id,\n" +
|
||||
"\tspecs,\n" +
|
||||
"\tsimple_specs,\n" +
|
||||
"\tfreight_template_id,\n" +
|
||||
"\tgoods_name,\n" +
|
||||
"\tsn,\n" +
|
||||
"\tbrand_id,\n" +
|
||||
"\tcategory_path,\n" +
|
||||
"\tgoods_unit,\n" +
|
||||
"\tselling_point,\n" +
|
||||
"\tweight,\n" +
|
||||
"\tmarket_enable,\n" +
|
||||
"\tintro,\n" +
|
||||
"\tprice,\n" +
|
||||
"\tcost,\n" +
|
||||
"\tquantity,\n" +
|
||||
"\tgrade,\n" +
|
||||
"\tthumbnail,\n" +
|
||||
"\tsmall,\n" +
|
||||
"\tstore_category_path,\n" +
|
||||
"\tstore_id,\n" +
|
||||
"\tstore_name,\n" +
|
||||
"\tauth_flag,\n" +
|
||||
"\tself_operated,\n" +
|
||||
"\tmobile_intro,\n" +
|
||||
"\trecommend,\n" +
|
||||
"\tsales_model,\n" +
|
||||
"\tgoods_type,\n" +
|
||||
"\tcreate_by,\n" +
|
||||
"\tcreate_time,\n" +
|
||||
"\tupdate_time,\n" +
|
||||
"\tdelete_flag \n" +
|
||||
")\n" +
|
||||
" VALUES\n" +
|
||||
"(\n" +
|
||||
"\t#{goodsSku.id},\n" +
|
||||
"\t#{goodsSku.goodsId},\n" +
|
||||
"\t#{goodsSku.specs},\n" +
|
||||
"\t#{goodsSku.simpleSpecs},\n" +
|
||||
"\t#{goodsSku.freightTemplateId},\n" +
|
||||
"\t#{goodsSku.goodsName},\n" +
|
||||
"\t#{goodsSku.sn},\n" +
|
||||
"\t#{goodsSku.brandId},\n" +
|
||||
"\t#{goodsSku.categoryPath},\n" +
|
||||
"\t#{goodsSku.goodsUnit},\n" +
|
||||
"\t#{goodsSku.sellingPoint},\n" +
|
||||
"\t#{goodsSku.weight},\n" +
|
||||
"\t#{goodsSku.marketEnable},\n" +
|
||||
"\t#{goodsSku.intro},\n" +
|
||||
"\t#{goodsSku.price},\n" +
|
||||
"\t#{goodsSku.cost},\n" +
|
||||
"\t#{goodsSku.quantity},\n" +
|
||||
"\t#{goodsSku.grade},\n" +
|
||||
"\t#{goodsSku.thumbnail},\n" +
|
||||
"\t#{goodsSku.small},\n" +
|
||||
"\t#{goodsSku.storeCategoryPath},\n" +
|
||||
"\t#{goodsSku.storeId},\n" +
|
||||
"\t#{goodsSku.storeName},\n" +
|
||||
"\t#{goodsSku.authFlag},\n" +
|
||||
"\t#{goodsSku.selfOperated},\n" +
|
||||
"\t#{goodsSku.mobileIntro},\n" +
|
||||
"\t#{goodsSku.recommend},\n" +
|
||||
"\t#{goodsSku.salesModel},\n" +
|
||||
"\t#{goodsSku.goodsType},\n" +
|
||||
"\t#{goodsSku.createBy},\n" +
|
||||
"\t#{goodsSku.createTime},\n" +
|
||||
"\t#{goodsSku.updateTime},\n" +
|
||||
"\t#{goodsSku.deleteFlag}\n" +
|
||||
")")
|
||||
int replaceGoodsSku(@Param("goodsSku") GoodsSku goodsSku);
|
||||
|
||||
|
||||
/**
|
||||
* 分页查询商品skuDTO
|
||||
*
|
||||
* @param page 分页
|
||||
* @param queryWrapper 查询条件
|
||||
* @return 售后VO分页
|
||||
*/
|
||||
@Select("SELECT *,g.params as params FROM li_goods_sku gs inner join li_goods g on gs.goods_id = g.id ${ew.customSqlSegment}")
|
||||
IPage<GoodsSkuDTO> queryByParams(IPage<GoodsSkuDTO> page, @Param(Constants.WRAPPER) Wrapper<GoodsSkuDTO> queryWrapper);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package cn.lili.modules.goods.mapper;
|
||||
|
||||
import cn.lili.modules.goods.entity.dos.Wholesale;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author paulG
|
||||
* @since 2022/5/24
|
||||
**/
|
||||
public interface WholesaleMapper extends BaseMapper<Wholesale> {
|
||||
}
|
||||
@@ -4,9 +4,6 @@ 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.util.List;
|
||||
|
||||
@@ -16,7 +13,6 @@ import java.util.List;
|
||||
* @author pikachu
|
||||
* @since 2020-03-02 16:44:56
|
||||
*/
|
||||
@CacheConfig(cacheNames = "{category}")
|
||||
public interface CategoryService extends IService<Category> {
|
||||
|
||||
|
||||
@@ -35,7 +31,6 @@ public interface CategoryService extends IService<Category> {
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Cacheable(key = "#id")
|
||||
Category getCategoryById(String id);
|
||||
|
||||
/**
|
||||
@@ -99,7 +94,6 @@ public interface CategoryService extends IService<Category> {
|
||||
* @param category 商品分类信息
|
||||
* @return 修改结果
|
||||
*/
|
||||
@CacheEvict(key = "#category.id")
|
||||
void updateCategory(Category category);
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,4 +36,11 @@ public interface GoodsGalleryService extends IService<GoodsGallery> {
|
||||
*/
|
||||
List<GoodsGallery> goodsGalleryList(String goodsId);
|
||||
|
||||
/**
|
||||
* 根据商品 id删除商品相册缩略图
|
||||
*
|
||||
* @param goodsId 商品ID
|
||||
*/
|
||||
void removeByGoodsId(String goodsId);
|
||||
|
||||
}
|
||||
@@ -129,6 +129,17 @@ public interface GoodsService extends IService<Goods> {
|
||||
*/
|
||||
Boolean updateGoodsMarketAble(List<String> goodsIds, GoodsStatusEnum goodsStatusEnum, String underReason);
|
||||
|
||||
|
||||
/**
|
||||
* 更新商品上架状态状态
|
||||
*
|
||||
* @param storeId 店铺ID
|
||||
* @param goodsStatusEnum 更新的商品状态
|
||||
* @param underReason 下架原因
|
||||
* @return 更新结果
|
||||
*/
|
||||
Boolean updateGoodsMarketAbleByStoreId(String storeId, GoodsStatusEnum goodsStatusEnum, String underReason);
|
||||
|
||||
/**
|
||||
* 更新商品上架状态状态
|
||||
*
|
||||
|
||||
@@ -3,10 +3,14 @@ package cn.lili.modules.goods.service;
|
||||
import cn.lili.cache.CachePrefix;
|
||||
import cn.lili.modules.goods.entity.dos.Goods;
|
||||
import cn.lili.modules.goods.entity.dos.GoodsSku;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsSkuDTO;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsSkuStockDTO;
|
||||
import cn.lili.modules.goods.entity.vos.GoodsSkuVO;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
@@ -43,19 +47,18 @@ public interface GoodsSkuService extends IService<GoodsSku> {
|
||||
/**
|
||||
* 添加商品sku
|
||||
*
|
||||
* @param skuList sku列表
|
||||
* @param goods 商品信息
|
||||
* @param goods 商品信息
|
||||
* @param goodsOperationDTO 商品操作信息
|
||||
*/
|
||||
void add(List<Map<String, Object>> skuList, Goods goods);
|
||||
void add(Goods goods, GoodsOperationDTO goodsOperationDTO);
|
||||
|
||||
/**
|
||||
* 更新商品sku
|
||||
*
|
||||
* @param skuList sku列表
|
||||
* @param goods 商品信息
|
||||
* @param regeneratorSkuFlag 是否是否重新生成sku
|
||||
* @param goods 商品信息
|
||||
* @param goodsOperationDTO 商品操作信息
|
||||
*/
|
||||
void update(List<Map<String, Object>> skuList, Goods goods, Boolean regeneratorSkuFlag);
|
||||
void update(Goods goods, GoodsOperationDTO goodsOperationDTO);
|
||||
|
||||
/**
|
||||
* 更新商品sku
|
||||
@@ -79,6 +82,14 @@ public interface GoodsSkuService extends IService<GoodsSku> {
|
||||
*/
|
||||
GoodsSku getGoodsSkuByIdFromCache(String id);
|
||||
|
||||
/**
|
||||
* 从缓存中获取可参与促销商品
|
||||
*
|
||||
* @param skuId skuid
|
||||
* @return 商品详情
|
||||
*/
|
||||
GoodsSku getCanPromotionGoodsSkuByIdFromCache(String skuId);
|
||||
|
||||
/**
|
||||
* 获取商品sku详情
|
||||
*
|
||||
@@ -136,6 +147,16 @@ public interface GoodsSkuService extends IService<GoodsSku> {
|
||||
*/
|
||||
IPage<GoodsSku> getGoodsSkuByPage(GoodsSearchParams searchParams);
|
||||
|
||||
|
||||
/**
|
||||
* 分页查询商品sku信息
|
||||
*
|
||||
* @param page 分页参数
|
||||
* @param queryWrapper 查询参数
|
||||
* @return 商品sku信息
|
||||
*/
|
||||
IPage<GoodsSkuDTO> getGoodsSkuDTOByPage(Page<GoodsSkuDTO> page, Wrapper<GoodsSkuDTO> queryWrapper);
|
||||
|
||||
/**
|
||||
* 列表查询商品sku信息
|
||||
*
|
||||
@@ -151,6 +172,15 @@ public interface GoodsSkuService extends IService<GoodsSku> {
|
||||
*/
|
||||
void updateGoodsSkuStatus(Goods goods);
|
||||
|
||||
/**
|
||||
* 更新商品sku状态根据店铺id
|
||||
*
|
||||
* @param storeId 店铺id
|
||||
* @param marketEnable 市场启用状态
|
||||
* @param authFlag 审核状态
|
||||
*/
|
||||
void updateGoodsSkuStatusByStoreId(String storeId, String marketEnable, String authFlag);
|
||||
|
||||
/**
|
||||
* 发送生成ES商品索引
|
||||
*
|
||||
@@ -202,4 +232,20 @@ public interface GoodsSkuService extends IService<GoodsSku> {
|
||||
* @return 全部skuId的集合
|
||||
*/
|
||||
List<String> getSkuIdsByGoodsId(String goodsId);
|
||||
|
||||
/**
|
||||
* 删除并且新增sku,即覆盖之前信息
|
||||
*
|
||||
* @param goodsSkus 商品sku集合
|
||||
* @return
|
||||
*/
|
||||
boolean deleteAndInsertGoodsSkus(List<GoodsSku> goodsSkus);
|
||||
|
||||
/**
|
||||
* 统计sku总数
|
||||
*
|
||||
* @param storeId 店铺id
|
||||
* @return sku总数
|
||||
*/
|
||||
Long countSkuNum(String storeId);
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public interface StudioService extends IService<Studio> {
|
||||
* @param status 直播间状态
|
||||
* @return 直播间分页
|
||||
*/
|
||||
IPage<Studio> studioList(PageVO pageVO, Integer recommend, String status);
|
||||
IPage<StudioVO> studioList(PageVO pageVO, Integer recommend, String status);
|
||||
|
||||
/**
|
||||
* 修改直播间状态
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package cn.lili.modules.goods.service;
|
||||
|
||||
import cn.lili.modules.goods.entity.dos.Wholesale;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author paulG
|
||||
* @since 2022/5/24
|
||||
**/
|
||||
public interface WholesaleService extends IService<Wholesale> {
|
||||
|
||||
|
||||
List<Wholesale> findByGoodsId(String goodsId);
|
||||
|
||||
Boolean removeByGoodsId(String goodsId);
|
||||
|
||||
/**
|
||||
* 匹配批发规则
|
||||
*
|
||||
* @param goodsId 商品规则
|
||||
* @param num 数量
|
||||
* @return 批发规则
|
||||
*/
|
||||
Wholesale match(String goodsId, Integer num);
|
||||
|
||||
}
|
||||
@@ -19,6 +19,9 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -36,6 +39,7 @@ import java.util.stream.Collectors;
|
||||
* @since 2020-02-23 15:18:56
|
||||
*/
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "{CATEGORY}")
|
||||
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {
|
||||
|
||||
private static final String DELETE_FLAG_COLUMN = "delete_flag";
|
||||
@@ -60,6 +64,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(key = "#id")
|
||||
public Category getCategoryById(String id) {
|
||||
return this.getById(id);
|
||||
}
|
||||
@@ -216,6 +221,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(key = "#category.id")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateCategory(Category category) {
|
||||
//判断分类佣金是否正确
|
||||
@@ -242,6 +248,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
|
||||
|
||||
|
||||
@Override
|
||||
@CacheEvict(key = "#id")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(String id) {
|
||||
this.removeById(id);
|
||||
@@ -253,6 +260,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(key = "#categoryId")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateCategoryStatus(String categoryId, Boolean enableOperations) {
|
||||
//禁用子分类
|
||||
@@ -335,7 +343,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
|
||||
return item.getChildren();
|
||||
}
|
||||
if (item.getChildren() != null && !item.getChildren().isEmpty()) {
|
||||
return getChildren(parentId, categoryVOList);
|
||||
return getChildren(parentId, item.getChildren());
|
||||
}
|
||||
}
|
||||
return categoryVOList;
|
||||
@@ -346,5 +354,6 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
|
||||
*/
|
||||
private void removeCache() {
|
||||
cache.remove(CachePrefix.CATEGORY.getPrefix());
|
||||
cache.remove(CachePrefix.CATEGORY_ARRAY.getPrefix());
|
||||
}
|
||||
}
|
||||
@@ -75,4 +75,14 @@ public class GoodsGalleryServiceImpl extends ServiceImpl<GoodsGalleryMapper, Goo
|
||||
//根据商品id查询商品相册
|
||||
return this.baseMapper.selectList(new QueryWrapper<GoodsGallery>().eq("goods_id", goodsId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商品 id删除商品相册缩略图
|
||||
*
|
||||
* @param goodsId 商品ID
|
||||
*/
|
||||
@Override
|
||||
public void removeByGoodsId(String goodsId) {
|
||||
this.baseMapper.delete(new UpdateWrapper<GoodsGallery>().eq("goods_id", goodsId));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.lili.modules.goods.serviceimpl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
@@ -14,6 +15,7 @@ import cn.lili.common.security.enums.UserEnums;
|
||||
import cn.lili.modules.goods.entity.dos.Category;
|
||||
import cn.lili.modules.goods.entity.dos.Goods;
|
||||
import cn.lili.modules.goods.entity.dos.GoodsGallery;
|
||||
import cn.lili.modules.goods.entity.dos.Wholesale;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsOperationFuLuDTO;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
|
||||
@@ -23,10 +25,7 @@ import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
|
||||
import cn.lili.modules.goods.entity.vos.GoodsSkuVO;
|
||||
import cn.lili.modules.goods.entity.vos.GoodsVO;
|
||||
import cn.lili.modules.goods.mapper.GoodsMapper;
|
||||
import cn.lili.modules.goods.service.CategoryService;
|
||||
import cn.lili.modules.goods.service.GoodsGalleryService;
|
||||
import cn.lili.modules.goods.service.GoodsService;
|
||||
import cn.lili.modules.goods.service.GoodsSkuService;
|
||||
import cn.lili.modules.goods.service.*;
|
||||
import cn.lili.modules.member.entity.dos.MemberEvaluation;
|
||||
import cn.lili.modules.member.entity.enums.EvaluationGradeEnum;
|
||||
import cn.lili.modules.member.service.MemberEvaluationService;
|
||||
@@ -111,6 +110,9 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
|
||||
@Autowired
|
||||
private FreightTemplateService freightTemplateService;
|
||||
|
||||
@Autowired
|
||||
private WholesaleService wholesaleService;
|
||||
|
||||
@Autowired
|
||||
private Cache<GoodsVO> cache;
|
||||
|
||||
@@ -171,7 +173,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
|
||||
//添加商品
|
||||
this.save(goods);
|
||||
//添加商品sku信息
|
||||
this.goodsSkuService.add(goodsOperationDTO.getSkuList(), goods);
|
||||
this.goodsSkuService.add(goods, goodsOperationDTO);
|
||||
//添加相册
|
||||
if (goodsOperationDTO.getGoodsGalleryList() != null && !goodsOperationDTO.getGoodsGalleryList().isEmpty()) {
|
||||
this.goodsGalleryService.add(goodsOperationDTO.getGoodsGalleryList(), goods.getId());
|
||||
@@ -220,7 +222,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
|
||||
//修改商品
|
||||
this.updateById(goods);
|
||||
//修改商品sku信息
|
||||
this.goodsSkuService.update(goodsOperationDTO.getSkuList(), goods, goodsOperationDTO.getRegeneratorSkuFlag());
|
||||
this.goodsSkuService.update(goods, goodsOperationDTO);
|
||||
//添加相册
|
||||
if (goodsOperationDTO.getGoodsGalleryList() != null && !goodsOperationDTO.getGoodsGalleryList().isEmpty()) {
|
||||
this.goodsGalleryService.add(goodsOperationDTO.getGoodsGalleryList(), goods.getId());
|
||||
@@ -302,6 +304,12 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
|
||||
if (CharSequenceUtil.isNotEmpty(goods.getParams())) {
|
||||
goodsVO.setGoodsParamsDTOList(JSONUtil.toList(goods.getParams(), GoodsParamsDTO.class));
|
||||
}
|
||||
|
||||
List<Wholesale> wholesaleList = wholesaleService.findByGoodsId(goodsId);
|
||||
if (CollUtil.isNotEmpty(wholesaleList)) {
|
||||
goodsVO.setWholesaleList(wholesaleList);
|
||||
}
|
||||
|
||||
cache.put(CachePrefix.GOODS.getPrefix() + goodsId, goodsVO);
|
||||
return goodsVO;
|
||||
}
|
||||
@@ -325,6 +333,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean auditGoods(List<String> goodsIds, GoodsAuthEnum goodsAuthEnum) {
|
||||
List<String> goodsCacheKeys = new ArrayList<>();
|
||||
boolean result = false;
|
||||
for (String goodsId : goodsIds) {
|
||||
Goods goods = this.checkExist(goodsId);
|
||||
@@ -332,12 +341,13 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
|
||||
result = this.updateById(goods);
|
||||
goodsSkuService.updateGoodsSkuStatus(goods);
|
||||
//删除之前的缓存
|
||||
cache.remove(CachePrefix.GOODS.getPrefix() + goodsId);
|
||||
goodsCacheKeys.add(CachePrefix.GOODS.getPrefix() + goodsId);
|
||||
//商品审核消息
|
||||
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.GOODS_AUDIT.name();
|
||||
//发送mq消息
|
||||
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(goods), RocketmqSendCallbackBuilder.commonCallback());
|
||||
}
|
||||
cache.multiDel(goodsCacheKeys);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -361,13 +371,30 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
|
||||
LambdaQueryWrapper<Goods> queryWrapper = this.getQueryWrapperByStoreAuthority();
|
||||
queryWrapper.in(Goods::getId, goodsIds);
|
||||
List<Goods> goodsList = this.list(queryWrapper);
|
||||
for (Goods goods : goodsList) {
|
||||
goodsSkuService.updateGoodsSkuStatus(goods);
|
||||
}
|
||||
this.updateGoodsStatus(goodsIds, goodsStatusEnum, goodsList);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (GoodsStatusEnum.DOWN.equals(goodsStatusEnum)) {
|
||||
this.deleteEsGoods(goodsIds);
|
||||
}
|
||||
/**
|
||||
* 更新商品上架状态状态
|
||||
*
|
||||
* @param storeId 店铺ID
|
||||
* @param goodsStatusEnum 更新的商品状态
|
||||
* @param underReason 下架原因
|
||||
* @return 更新结果
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateGoodsMarketAbleByStoreId(String storeId, GoodsStatusEnum goodsStatusEnum, String underReason) {
|
||||
boolean result;
|
||||
|
||||
LambdaUpdateWrapper<Goods> updateWrapper = this.getUpdateWrapperByStoreAuthority();
|
||||
updateWrapper.set(Goods::getMarketEnable, goodsStatusEnum.name());
|
||||
updateWrapper.set(Goods::getUnderMessage, underReason);
|
||||
updateWrapper.eq(Goods::getStoreId, storeId);
|
||||
result = this.update(updateWrapper);
|
||||
|
||||
//修改规格商品
|
||||
this.goodsSkuService.updateGoodsSkuStatusByStoreId(storeId, goodsStatusEnum.name(), null);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -394,12 +421,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
|
||||
LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(Goods::getId, goodsIds);
|
||||
List<Goods> goodsList = this.list(queryWrapper);
|
||||
for (Goods goods : goodsList) {
|
||||
goodsSkuService.updateGoodsSkuStatus(goods);
|
||||
}
|
||||
if (GoodsStatusEnum.DOWN.equals(goodsStatusEnum)) {
|
||||
this.deleteEsGoods(goodsIds);
|
||||
}
|
||||
this.updateGoodsStatus(goodsIds, goodsStatusEnum, goodsList);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -417,13 +439,15 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
|
||||
LambdaQueryWrapper<Goods> queryWrapper = this.getQueryWrapperByStoreAuthority();
|
||||
queryWrapper.in(Goods::getId, goodsIds);
|
||||
List<Goods> goodsList = this.list(queryWrapper);
|
||||
List<String> goodsCacheKeys = new ArrayList<>();
|
||||
for (Goods goods : goodsList) {
|
||||
//修改SKU状态
|
||||
goodsSkuService.updateGoodsSkuStatus(goods);
|
||||
goodsCacheKeys.add(CachePrefix.GOODS.getPrefix() + goods.getId());
|
||||
}
|
||||
|
||||
//删除缓存
|
||||
cache.multiDel(goodsCacheKeys);
|
||||
this.deleteEsGoods(goodsIds);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -503,11 +527,43 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
|
||||
return this.count(
|
||||
new LambdaQueryWrapper<Goods>()
|
||||
.eq(Goods::getStoreId, storeId)
|
||||
.eq(Goods::getDeleteFlag, Boolean.FALSE)
|
||||
.eq(Goods::getAuthFlag, GoodsAuthEnum.PASS.name())
|
||||
.eq(Goods::getMarketEnable, GoodsStatusEnum.UPPER.name()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 更新店铺商品数量
|
||||
*
|
||||
* @param storeId 信息体
|
||||
*/
|
||||
void updateGoodsNum(String storeId) {
|
||||
Long num = goodsSkuService.countSkuNum(storeId);
|
||||
storeService.updateStoreGoodsNum(storeId, num);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新商品状态
|
||||
*
|
||||
* @param goodsIds 商品ID
|
||||
* @param goodsStatusEnum 商品状态
|
||||
* @param goodsList 商品列表
|
||||
*/
|
||||
private void updateGoodsStatus(List<String> goodsIds, GoodsStatusEnum goodsStatusEnum, List<Goods> goodsList) {
|
||||
List<String> goodsCacheKeys = new ArrayList<>();
|
||||
for (Goods goods : goodsList) {
|
||||
goodsCacheKeys.add(CachePrefix.GOODS.getPrefix() + goods.getId());
|
||||
goodsSkuService.updateGoodsSkuStatus(goods);
|
||||
}
|
||||
cache.multiDel(goodsCacheKeys);
|
||||
|
||||
if (GoodsStatusEnum.DOWN.equals(goodsStatusEnum)) {
|
||||
this.deleteEsGoods(goodsIds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送删除es索引的信息
|
||||
*
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package cn.lili.modules.goods.serviceimpl;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
@@ -10,25 +9,29 @@ import cn.lili.cache.Cache;
|
||||
import cn.lili.cache.CachePrefix;
|
||||
import cn.lili.common.enums.PromotionTypeEnum;
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.event.TransactionCommitSendMQEvent;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.properties.RocketmqCustomProperties;
|
||||
import cn.lili.common.security.context.UserContext;
|
||||
import cn.lili.common.utils.SnowFlake;
|
||||
import cn.lili.modules.goods.entity.dos.Goods;
|
||||
import cn.lili.modules.goods.entity.dos.GoodsGallery;
|
||||
import cn.lili.modules.goods.entity.dos.GoodsSku;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsSkuDTO;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsSkuStockDTO;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
|
||||
import cn.lili.modules.goods.entity.vos.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.goods.service.*;
|
||||
import cn.lili.modules.goods.sku.GoodsSkuBuilder;
|
||||
import cn.lili.modules.goods.sku.render.SalesModelRender;
|
||||
import cn.lili.modules.member.entity.dos.FootPrint;
|
||||
import cn.lili.modules.member.entity.dto.EvaluationQueryParams;
|
||||
import cn.lili.modules.member.entity.enums.EvaluationGradeEnum;
|
||||
@@ -37,16 +40,17 @@ import cn.lili.modules.promotion.entity.dos.PromotionGoods;
|
||||
import cn.lili.modules.promotion.entity.dto.search.PromotionGoodsSearchParams;
|
||||
import cn.lili.modules.promotion.entity.enums.CouponGetEnum;
|
||||
import cn.lili.modules.promotion.service.PromotionGoodsService;
|
||||
import cn.lili.modules.search.entity.dos.EsGoodsAttribute;
|
||||
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
|
||||
import cn.lili.modules.search.service.EsGoodsIndexService;
|
||||
import cn.lili.modules.search.utils.EsIndexUtil;
|
||||
import cn.lili.mybatis.util.PageUtil;
|
||||
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
|
||||
import cn.lili.rocketmq.tags.GoodsTagsEnum;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -113,35 +117,42 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
@Autowired
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
@Autowired
|
||||
private WholesaleService wholesaleService;
|
||||
|
||||
@Autowired
|
||||
private List<SalesModelRender> salesModelRenders;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void add(List<Map<String, Object>> skuList, Goods goods) {
|
||||
// 检查是否需要生成索引
|
||||
List<GoodsSku> newSkuList;
|
||||
//如果有规格
|
||||
if (skuList != null && !skuList.isEmpty()) {
|
||||
// 添加商品sku
|
||||
newSkuList = this.addGoodsSku(skuList, goods);
|
||||
} else {
|
||||
public void add(Goods goods, GoodsOperationDTO goodsOperationDTO) {
|
||||
// 是否存在规格
|
||||
if (goodsOperationDTO.getSkuList() == null || goodsOperationDTO.getSkuList().isEmpty()) {
|
||||
throw new ServiceException(ResultCode.MUST_HAVE_GOODS_SKU);
|
||||
}
|
||||
// 检查是否需要生成索引
|
||||
List<GoodsSku> goodsSkus = GoodsSkuBuilder.buildBatch(goods, goodsOperationDTO);
|
||||
renderGoodsSkuList(goodsSkus, goodsOperationDTO);
|
||||
|
||||
this.updateStock(newSkuList);
|
||||
if (!newSkuList.isEmpty()) {
|
||||
generateEs(goods);
|
||||
if (!goodsSkus.isEmpty()) {
|
||||
this.saveOrUpdateBatch(goodsSkus);
|
||||
this.updateStock(goodsSkus);
|
||||
this.generateEs(goods);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(List<Map<String, Object>> skuList, Goods goods, Boolean regeneratorSkuFlag) {
|
||||
public void update(Goods goods, GoodsOperationDTO goodsOperationDTO) {
|
||||
// 是否存在规格
|
||||
if (skuList == null || skuList.isEmpty()) {
|
||||
if (goodsOperationDTO.getSkuList() == null || goodsOperationDTO.getSkuList().isEmpty()) {
|
||||
throw new ServiceException(ResultCode.MUST_HAVE_GOODS_SKU);
|
||||
}
|
||||
List<GoodsSku> newSkuList;
|
||||
List<GoodsSku> skuList;
|
||||
//删除旧的sku信息
|
||||
if (Boolean.TRUE.equals(regeneratorSkuFlag)) {
|
||||
if (Boolean.TRUE.equals(goodsOperationDTO.getRegeneratorSkuFlag())) {
|
||||
skuList = GoodsSkuBuilder.buildBatch(goods, goodsOperationDTO);
|
||||
renderGoodsSkuList(skuList, goodsOperationDTO);
|
||||
List<GoodsSkuVO> goodsListByGoodsId = getGoodsListByGoodsId(goods.getId());
|
||||
List<String> oldSkuIds = new ArrayList<>();
|
||||
//删除旧索引
|
||||
@@ -149,36 +160,32 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
oldSkuIds.add(goodsSkuVO.getId());
|
||||
cache.remove(GoodsSkuService.getCacheKeys(goodsSkuVO.getId()));
|
||||
}
|
||||
goodsIndexService.deleteIndexByIds(oldSkuIds);
|
||||
this.removeByIds(oldSkuIds);
|
||||
|
||||
this.remove(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getId()));
|
||||
//删除sku相册
|
||||
goodsGalleryService.removeByIds(oldSkuIds);
|
||||
// 添加商品sku
|
||||
newSkuList = this.addGoodsSku(skuList, goods);
|
||||
goodsGalleryService.removeByGoodsId(goods.getId());
|
||||
|
||||
//发送mq消息
|
||||
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.SKU_DELETE.name();
|
||||
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(oldSkuIds), RocketmqSendCallbackBuilder.commonCallback());
|
||||
} else {
|
||||
newSkuList = new ArrayList<>();
|
||||
for (Map<String, Object> map : skuList) {
|
||||
GoodsSku sku = new GoodsSku();
|
||||
//设置商品信息
|
||||
goodsInfo(sku, goods);
|
||||
//设置商品规格信息
|
||||
skuInfo(sku, goods, map, null);
|
||||
newSkuList.add(sku);
|
||||
skuList = new ArrayList<>();
|
||||
for (Map<String, Object> map : goodsOperationDTO.getSkuList()) {
|
||||
GoodsSku sku = GoodsSkuBuilder.build(goods, map, goodsOperationDTO);
|
||||
renderGoodsSku(sku, goodsOperationDTO);
|
||||
skuList.add(sku);
|
||||
//如果商品状态值不对,则es索引移除
|
||||
if (goods.getAuthFlag().equals(GoodsAuthEnum.PASS.name()) && goods.getMarketEnable().equals(GoodsStatusEnum.UPPER.name())) {
|
||||
goodsIndexService.deleteIndexById(sku.getId());
|
||||
this.clearCache(sku.getId());
|
||||
}
|
||||
}
|
||||
this.updateBatchById(newSkuList);
|
||||
}
|
||||
this.updateStock(newSkuList);
|
||||
if (GoodsAuthEnum.PASS.name().equals(goods.getAuthFlag()) && !newSkuList.isEmpty()) {
|
||||
generateEs(goods);
|
||||
if (!skuList.isEmpty()) {
|
||||
this.remove(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getId()));
|
||||
this.saveOrUpdateBatch(skuList);
|
||||
this.updateStock(skuList);
|
||||
this.generateEs(goods);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,6 +238,15 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
return goodsSku;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GoodsSku getCanPromotionGoodsSkuByIdFromCache(String skuId) {
|
||||
GoodsSku goodsSku = this.getGoodsSkuByIdFromCache(skuId);
|
||||
if (goodsSku != null && GoodsSalesModeEnum.WHOLESALE.name().equals(goodsSku.getSalesModel())) {
|
||||
throw new ServiceException(ResultCode.PROMOTION_GOODS_DO_NOT_JOIN_WHOLESALE, goodsSku.getGoodsName());
|
||||
}
|
||||
return goodsSku;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getGoodsSkuDetail(String goodsId, String skuId) {
|
||||
Map<String, Object> map = new HashMap<>(16);
|
||||
@@ -244,13 +260,16 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
GoodsSku goodsSku = this.getGoodsSkuByIdFromCache(skuId);
|
||||
//如果使用商品ID无法查询SKU则返回错误
|
||||
if (goodsVO == null || goodsSku == null) {
|
||||
//发送mq消息
|
||||
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.GOODS_DELETE.name();
|
||||
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(Collections.singletonList(goodsId)), RocketmqSendCallbackBuilder.commonCallback());
|
||||
throw new ServiceException(ResultCode.GOODS_NOT_EXIST);
|
||||
}
|
||||
|
||||
//商品下架||商品未审核通过||商品删除,则提示:商品已下架
|
||||
if (GoodsStatusEnum.DOWN.name().equals(goodsVO.getMarketEnable())
|
||||
|| !GoodsAuthEnum.PASS.name().equals(goodsVO.getAuthFlag())
|
||||
|| Boolean.TRUE.equals(goodsVO.getDeleteFlag())) {
|
||||
if (GoodsStatusEnum.DOWN.name().equals(goodsVO.getMarketEnable()) || !GoodsAuthEnum.PASS.name().equals(goodsVO.getAuthFlag()) || Boolean.TRUE.equals(goodsVO.getDeleteFlag())) {
|
||||
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.GOODS_DELETE.name();
|
||||
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(Collections.singletonList(goodsId)), RocketmqSendCallbackBuilder.commonCallback());
|
||||
throw new ServiceException(ResultCode.GOODS_NOT_EXIST);
|
||||
}
|
||||
|
||||
@@ -269,13 +288,10 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
promotionMap = promotionMap.entrySet().stream().parallel().filter(i -> {
|
||||
JSONObject jsonObject = JSONUtil.parseObj(i.getValue());
|
||||
// 过滤活动赠送优惠券和无效时间的活动
|
||||
return (jsonObject.get("getType") == null || jsonObject.get("getType", String.class).equals(CouponGetEnum.FREE.name())) &&
|
||||
(jsonObject.get("startTime") != null && jsonObject.get("startTime", Date.class).getTime() <= System.currentTimeMillis()) &&
|
||||
(jsonObject.get("endTime") == null || jsonObject.get("endTime", Date.class).getTime() >= System.currentTimeMillis());
|
||||
return (jsonObject.get("getType") == null || jsonObject.get("getType", String.class).equals(CouponGetEnum.FREE.name())) && (jsonObject.get("startTime") != null && jsonObject.get("startTime", Date.class).getTime() <= System.currentTimeMillis()) && (jsonObject.get("endTime") == null || jsonObject.get("endTime", Date.class).getTime() >= System.currentTimeMillis());
|
||||
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
|
||||
Optional<Map.Entry<String, Object>> containsPromotion = promotionMap.entrySet().stream().filter(i ->
|
||||
i.getKey().contains(PromotionTypeEnum.SECKILL.name()) || i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst();
|
||||
Optional<Map.Entry<String, Object>> containsPromotion = promotionMap.entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.SECKILL.name()) || i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst();
|
||||
if (containsPromotion.isPresent()) {
|
||||
JSONObject jsonObject = JSONUtil.parseObj(containsPromotion.get().getValue());
|
||||
PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
|
||||
@@ -296,6 +312,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
|
||||
//获取分类
|
||||
String[] split = goodsSkuDetail.getCategoryPath().split(",");
|
||||
map.put("wholesaleList", wholesaleService.findByGoodsId(goodsSkuDetail.getGoodsId()));
|
||||
map.put("categoryName", categoryService.getCategoryNameByIds(Arrays.asList(split)));
|
||||
|
||||
//获取规格信息
|
||||
@@ -325,7 +342,8 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateGoodsSkuStatus(Goods goods) {
|
||||
LambdaUpdateWrapper<GoodsSku> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(GoodsSku::getGoodsId, goods.getId());
|
||||
updateWrapper.eq(CharSequenceUtil.isNotEmpty(goods.getId()), GoodsSku::getGoodsId, goods.getId());
|
||||
updateWrapper.eq(CharSequenceUtil.isNotEmpty(goods.getStoreId()), GoodsSku::getStoreId, goods.getStoreId());
|
||||
updateWrapper.set(GoodsSku::getMarketEnable, goods.getMarketEnable());
|
||||
updateWrapper.set(GoodsSku::getAuthFlag, goods.getAuthFlag());
|
||||
updateWrapper.set(GoodsSku::getDeleteFlag, goods.getDeleteFlag());
|
||||
@@ -337,7 +355,32 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
cache.put(GoodsSkuService.getCacheKeys(sku.getId()), sku);
|
||||
}
|
||||
if (!goodsSkus.isEmpty()) {
|
||||
generateEs(goods);
|
||||
this.generateEs(goods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新商品sku状态根据店铺id
|
||||
*
|
||||
* @param storeId 店铺id
|
||||
* @param marketEnable 市场启用状态
|
||||
* @param authFlag 审核状态
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateGoodsSkuStatusByStoreId(String storeId, String marketEnable, String authFlag) {
|
||||
LambdaUpdateWrapper<GoodsSku> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(GoodsSku::getStoreId, storeId);
|
||||
updateWrapper.set(CharSequenceUtil.isNotEmpty(marketEnable), GoodsSku::getMarketEnable, marketEnable);
|
||||
updateWrapper.set(CharSequenceUtil.isNotEmpty(authFlag), GoodsSku::getAuthFlag, authFlag);
|
||||
boolean update = this.update(updateWrapper);
|
||||
if (Boolean.TRUE.equals(update)) {
|
||||
if (GoodsStatusEnum.UPPER.name().equals(marketEnable)) {
|
||||
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("生成店铺商品", rocketmqCustomProperties.getGoodsTopic(), GoodsTagsEnum.GENERATOR_STORE_GOODS_INDEX.name(), storeId));
|
||||
} else if (GoodsStatusEnum.DOWN.name().equals(marketEnable)) {
|
||||
cache.vagueDel(CachePrefix.GOODS_SKU.getPrefix());
|
||||
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("删除店铺商品", rocketmqCustomProperties.getGoodsTopic(), GoodsTagsEnum.STORE_GOODS_DELETE.name(), storeId));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -362,7 +405,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
|
||||
@Override
|
||||
public List<GoodsSkuVO> getGoodsListByGoodsId(String goodsId) {
|
||||
List<GoodsSku> list = this.list(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goodsId));
|
||||
List<GoodsSku> list = this.list(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goodsId).orderByAsc(GoodsSku::getGoodsName));
|
||||
return this.getGoodsSkuVOList(list);
|
||||
}
|
||||
|
||||
@@ -423,6 +466,11 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
return this.page(PageUtil.initPage(searchParams), searchParams.queryWrapper());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<GoodsSkuDTO> getGoodsSkuDTOByPage(Page<GoodsSkuDTO> page, Wrapper<GoodsSkuDTO> queryWrapper) {
|
||||
return this.baseMapper.queryByParams(page, queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表查询商品sku信息
|
||||
*
|
||||
@@ -481,18 +529,14 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateGoodsStuck(List<GoodsSku> goodsSkus) {
|
||||
//商品id集合 hashset 去重复
|
||||
Set<String> goodsIds = new HashSet<>();
|
||||
for (GoodsSku sku : goodsSkus) {
|
||||
goodsIds.add(sku.getGoodsId());
|
||||
}
|
||||
Map<String, List<GoodsSku>> groupByGoodsIds = goodsSkus.stream().collect(Collectors.groupingBy(GoodsSku::getGoodsId));
|
||||
//获取相关的sku集合
|
||||
LambdaQueryWrapper<GoodsSku> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.in(GoodsSku::getGoodsId, goodsIds);
|
||||
lambdaQueryWrapper.in(GoodsSku::getGoodsId, groupByGoodsIds.keySet());
|
||||
List<GoodsSku> goodsSkuList = this.list(lambdaQueryWrapper);
|
||||
|
||||
//统计每个商品的库存
|
||||
for (String goodsId : goodsIds) {
|
||||
for (String goodsId : groupByGoodsIds.keySet()) {
|
||||
//库存
|
||||
Integer quantity = 0;
|
||||
for (GoodsSku goodsSku : goodsSkuList) {
|
||||
@@ -530,10 +574,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
|
||||
|
||||
//修改规格索引,发送mq消息
|
||||
Map<String, Object> updateIndexFieldsMap = EsIndexUtil.getUpdateIndexFieldsMap(
|
||||
MapUtil.builder(new HashMap<String, Object>()).put("id", goodsSku.getId()).build(),
|
||||
MapUtil.builder(new HashMap<String, Object>()).put("commentNum", goodsSku.getCommentNum()).put("highPraiseNum", highPraiseNum)
|
||||
.put("grade", grade).build());
|
||||
Map<String, Object> updateIndexFieldsMap = EsIndexUtil.getUpdateIndexFieldsMap(MapUtil.builder(new HashMap<String, Object>()).put("id", goodsSku.getId()).build(), MapUtil.builder(new HashMap<String, Object>()).put("commentNum", goodsSku.getCommentNum()).put("highPraiseNum", highPraiseNum).put("grade", grade).build());
|
||||
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.UPDATE_GOODS_INDEX_FIELD.name();
|
||||
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(updateIndexFieldsMap), RocketmqSendCallbackBuilder.commonCallback());
|
||||
|
||||
@@ -558,12 +599,38 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
* @param goods 商品信息
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void generateEs(Goods goods) {
|
||||
// 不生成没有审核通过且没有上架的商品
|
||||
if (!GoodsStatusEnum.UPPER.name().equals(goods.getMarketEnable()) || !GoodsAuthEnum.PASS.name().equals(goods.getAuthFlag())) {
|
||||
return;
|
||||
}
|
||||
applicationEventPublisher.publishEvent(new GeneratorEsGoodsIndexEvent("生成商品索引事件", goods.getId()));
|
||||
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("生成商品", rocketmqCustomProperties.getGoodsTopic(), GoodsTagsEnum.GENERATOR_GOODS_INDEX.name(), goods.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean deleteAndInsertGoodsSkus(List<GoodsSku> goodsSkus) {
|
||||
int count = 0;
|
||||
for (GoodsSku skus : goodsSkus) {
|
||||
if (CharSequenceUtil.isEmpty(skus.getId())) {
|
||||
skus.setId(SnowFlake.getIdStr());
|
||||
}
|
||||
count = this.baseMapper.replaceGoodsSku(skus);
|
||||
}
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long countSkuNum(String storeId) {
|
||||
LambdaQueryWrapper<GoodsSku> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
queryWrapper
|
||||
.eq(GoodsSku::getStoreId, storeId)
|
||||
.eq(GoodsSku::getDeleteFlag, Boolean.FALSE)
|
||||
.eq(GoodsSku::getAuthFlag, GoodsAuthEnum.PASS.name())
|
||||
.eq(GoodsSku::getMarketEnable, GoodsStatusEnum.UPPER.name());
|
||||
return this.count(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -584,152 +651,64 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
|
||||
|
||||
|
||||
/**
|
||||
* 增加sku集合
|
||||
* 批量渲染商品sku
|
||||
*
|
||||
* @param skuList sku列表
|
||||
* @param goods 商品信息
|
||||
* @param goodsSkuList sku集合
|
||||
* @param goodsOperationDTO 商品操作DTO
|
||||
*/
|
||||
List<GoodsSku> addGoodsSku(List<Map<String, Object>> skuList, Goods goods) {
|
||||
List<GoodsSku> skus = new ArrayList<>();
|
||||
for (Map<String, Object> skuVO : skuList) {
|
||||
Map<String, Object> resultMap = this.add(skuVO, goods);
|
||||
GoodsSku goodsSku = (GoodsSku) resultMap.get("goodsSku");
|
||||
if (goods.getSelfOperated() != null) {
|
||||
goodsSku.setSelfOperated(goods.getSelfOperated());
|
||||
}
|
||||
goodsSku.setGoodsType(goods.getGoodsType());
|
||||
skus.add(goodsSku);
|
||||
cache.put(GoodsSkuService.getStockCacheKey(goodsSku.getId()), goodsSku.getQuantity());
|
||||
void renderGoodsSkuList(List<GoodsSku> goodsSkuList, GoodsOperationDTO goodsOperationDTO) {
|
||||
// 商品销售模式渲染器
|
||||
salesModelRenders.stream().filter(i -> i.getSalesMode().equals(goodsOperationDTO.getSalesModel())).findFirst().ifPresent(i -> i.renderBatch(goodsSkuList, goodsOperationDTO));
|
||||
for (GoodsSku goodsSku : goodsSkuList) {
|
||||
extendOldSkuValue(goodsSku);
|
||||
this.renderImages(goodsSku);
|
||||
}
|
||||
this.saveBatch(skus);
|
||||
return skus;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品规格
|
||||
* 渲染商品sku
|
||||
*
|
||||
* @param map 规格属性
|
||||
* @param goods 商品
|
||||
* @return 规格商品
|
||||
* @param goodsSku sku
|
||||
* @param goodsOperationDTO 商品操作DTO
|
||||
*/
|
||||
private Map<String, Object> add(Map<String, Object> map, Goods goods) {
|
||||
Map<String, Object> resultMap = new HashMap<>(2);
|
||||
GoodsSku sku = new GoodsSku();
|
||||
|
||||
//商品索引
|
||||
EsGoodsIndex esGoodsIndex = new EsGoodsIndex();
|
||||
|
||||
//设置商品信息
|
||||
goodsInfo(sku, goods);
|
||||
//设置商品规格信息
|
||||
skuInfo(sku, goods, map, esGoodsIndex);
|
||||
|
||||
esGoodsIndex.setGoodsSku(sku);
|
||||
resultMap.put("goodsSku", sku);
|
||||
resultMap.put("goodsIndex", esGoodsIndex);
|
||||
return resultMap;
|
||||
void renderGoodsSku(GoodsSku goodsSku, GoodsOperationDTO goodsOperationDTO) {
|
||||
extendOldSkuValue(goodsSku);
|
||||
// 商品销售模式渲染器
|
||||
salesModelRenders.stream().filter(i -> i.getSalesMode().equals(goodsOperationDTO.getSalesModel())).findFirst().ifPresent(i -> i.renderSingle(goodsSku, goodsOperationDTO));
|
||||
this.renderImages(goodsSku);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置规格商品的商品信息
|
||||
* 将原sku的一些不会直接传递的值放到新的sku中
|
||||
*
|
||||
* @param sku 规格
|
||||
* @param goods 商品
|
||||
* @param goodsSku 商品sku
|
||||
*/
|
||||
private void goodsInfo(GoodsSku sku, Goods goods) {
|
||||
//商品基本信息
|
||||
sku.setGoodsId(goods.getId());
|
||||
|
||||
sku.setSellingPoint(goods.getSellingPoint());
|
||||
sku.setCategoryPath(goods.getCategoryPath());
|
||||
sku.setBrandId(goods.getBrandId());
|
||||
sku.setMarketEnable(goods.getMarketEnable());
|
||||
sku.setIntro(goods.getIntro());
|
||||
sku.setMobileIntro(goods.getMobileIntro());
|
||||
sku.setGoodsUnit(goods.getGoodsUnit());
|
||||
sku.setGrade(100D);
|
||||
//商品状态
|
||||
sku.setAuthFlag(goods.getAuthFlag());
|
||||
sku.setSalesModel(goods.getSalesModel());
|
||||
//卖家信息
|
||||
sku.setStoreId(goods.getStoreId());
|
||||
sku.setStoreName(goods.getStoreName());
|
||||
sku.setStoreCategoryPath(goods.getStoreCategoryPath());
|
||||
sku.setFreightTemplateId(goods.getTemplateId());
|
||||
sku.setRecommend(goods.getRecommend());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置商品规格信息
|
||||
*
|
||||
* @param sku 规格商品
|
||||
* @param goods 商品
|
||||
* @param map 规格信息
|
||||
* @param esGoodsIndex 商品索引
|
||||
*/
|
||||
private void skuInfo(GoodsSku sku, Goods goods, Map<String, Object> map, EsGoodsIndex esGoodsIndex) {
|
||||
|
||||
//规格简短信息
|
||||
StringBuilder simpleSpecs = new StringBuilder();
|
||||
//商品名称
|
||||
StringBuilder goodsName = new StringBuilder(goods.getGoodsName());
|
||||
//规格商品缩略图
|
||||
String thumbnail = "";
|
||||
String small = "";
|
||||
//规格值
|
||||
Map<String, Object> specMap = new HashMap<>(16);
|
||||
//商品属性
|
||||
List<EsGoodsAttribute> attributes = new ArrayList<>();
|
||||
|
||||
//获取规格信息
|
||||
for (Map.Entry<String, Object> spec : map.entrySet()) {
|
||||
//保存规格信息
|
||||
if (("id").equals(spec.getKey()) || ("sn").equals(spec.getKey()) || ("cost").equals(spec.getKey())
|
||||
|| ("price").equals(spec.getKey()) || ("quantity").equals(spec.getKey())
|
||||
|| ("weight").equals(spec.getKey())) {
|
||||
continue;
|
||||
} else {
|
||||
specMap.put(spec.getKey(), spec.getValue());
|
||||
if (("images").equals(spec.getKey())) {
|
||||
//设置规格商品缩略图
|
||||
List<Map<String, String>> images = (List<Map<String, String>>) spec.getValue();
|
||||
if (images == null || images.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
//设置规格商品缩略图
|
||||
//如果规格没有图片,则用商品图片复盖。有则增加规格图片,放在商品图片集合之前
|
||||
if (CharSequenceUtil.isNotEmpty(spec.getValue().toString())) {
|
||||
thumbnail = goodsGalleryService.getGoodsGallery(images.get(0).get("url")).getThumbnail();
|
||||
small = goodsGalleryService.getGoodsGallery(images.get(0).get("url")).getSmall();
|
||||
}
|
||||
} else {
|
||||
if (spec.getValue() != null) {
|
||||
//设置商品名称
|
||||
goodsName.append(" ").append(spec.getValue());
|
||||
//规格简短信息
|
||||
simpleSpecs.append(" ").append(spec.getValue());
|
||||
}
|
||||
}
|
||||
private void extendOldSkuValue(GoodsSku goodsSku) {
|
||||
if (CharSequenceUtil.isNotEmpty(goodsSku.getGoodsId())) {
|
||||
GoodsSku oldSku = this.getGoodsSkuByIdFromCache(goodsSku.getId());
|
||||
if (oldSku != null) {
|
||||
goodsSku.setCommentNum(oldSku.getCommentNum());
|
||||
goodsSku.setViewCount(oldSku.getViewCount());
|
||||
goodsSku.setBuyCount(oldSku.getBuyCount());
|
||||
goodsSku.setGrade(oldSku.getGrade());
|
||||
}
|
||||
}
|
||||
//设置规格信息
|
||||
sku.setGoodsName(goodsName.toString());
|
||||
sku.setThumbnail(thumbnail);
|
||||
sku.setSmall(small);
|
||||
}
|
||||
|
||||
//规格信息
|
||||
sku.setId(Convert.toStr(map.get("id"), ""));
|
||||
sku.setSn(Convert.toStr(map.get("sn")));
|
||||
sku.setWeight(Convert.toDouble(map.get("weight"), 0D));
|
||||
sku.setPrice(Convert.toDouble(map.get("price"), 0D));
|
||||
sku.setCost(Convert.toDouble(map.get("cost"), 0D));
|
||||
sku.setQuantity(Convert.toInt(map.get("quantity"), 0));
|
||||
sku.setSpecs(JSONUtil.toJsonStr(specMap));
|
||||
sku.setSimpleSpecs(simpleSpecs.toString());
|
||||
|
||||
if (esGoodsIndex != null) {
|
||||
//商品索引
|
||||
esGoodsIndex.setAttrList(attributes);
|
||||
/**
|
||||
* 渲染sku图片
|
||||
*
|
||||
* @param goodsSku sku
|
||||
*/
|
||||
void renderImages(GoodsSku goodsSku) {
|
||||
JSONObject jsonObject = JSONUtil.parseObj(goodsSku.getSpecs());
|
||||
List<Map<String, String>> images = jsonObject.get("images", List.class);
|
||||
if (images != null && !images.isEmpty()) {
|
||||
GoodsGallery goodsGallery = goodsGalleryService.getGoodsGallery(images.get(0).get("url"));
|
||||
goodsSku.setBig(goodsGallery.getOriginal());
|
||||
goodsSku.setOriginal(goodsGallery.getOriginal());
|
||||
goodsSku.setThumbnail(goodsGallery.getThumbnail());
|
||||
goodsSku.setSmall(goodsGallery.getSmall());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public class StoreGoodsLabelServiceImpl extends ServiceImpl<StoreGoodsLabelMappe
|
||||
StoreGoodsLabelVO storeGoodsLabelVO = new StoreGoodsLabelVO(storeGoodsLabel.getId(), storeGoodsLabel.getLabelName(), storeGoodsLabel.getLevel(), storeGoodsLabel.getSortOrder());
|
||||
List<StoreGoodsLabelVO> storeGoodsLabelVOChildList = new ArrayList<>();
|
||||
list.stream()
|
||||
.filter(label -> label.getParentId().equals(storeGoodsLabel.getId()))
|
||||
.filter(label -> label.getParentId() != null && label.getParentId().equals(storeGoodsLabel.getId()))
|
||||
.forEach(storeGoodsLabelChild -> storeGoodsLabelVOChildList.add(new StoreGoodsLabelVO(storeGoodsLabelChild.getId(), storeGoodsLabelChild.getLabelName(), storeGoodsLabelChild.getLevel(), storeGoodsLabelChild.getSortOrder())));
|
||||
storeGoodsLabelVO.setChildren(storeGoodsLabelVOChildList);
|
||||
storeGoodsLabelVOList.add(storeGoodsLabelVO);
|
||||
@@ -66,7 +66,7 @@ public class StoreGoodsLabelServiceImpl extends ServiceImpl<StoreGoodsLabelMappe
|
||||
storeGoodsLabelVOList.sort(Comparator.comparing(StoreGoodsLabelVO::getSortOrder));
|
||||
|
||||
if (!storeGoodsLabelVOList.isEmpty()) {
|
||||
cache.put(CachePrefix.CATEGORY.getPrefix() + storeId + "tree", storeGoodsLabelVOList);
|
||||
cache.put(CachePrefix.CATEGORY.getPrefix() + storeId, storeGoodsLabelVOList);
|
||||
}
|
||||
return storeGoodsLabelVOList;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cn.lili.modules.goods.serviceimpl;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
@@ -32,12 +33,15 @@ 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.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -117,7 +121,7 @@ public class StudioServiceImpl extends ServiceImpl<StudioMapper, Studio> impleme
|
||||
rocketmqCustomProperties.getPromotionTopic());
|
||||
|
||||
//直播间结束
|
||||
broadcastMessage = new BroadcastMessage(studio.getId(), StudioStatusEnum.START.name());
|
||||
broadcastMessage = new BroadcastMessage(studio.getId(), StudioStatusEnum.END.name());
|
||||
this.timeTrigger.edit(
|
||||
TimeExecuteConstant.BROADCAST_EXECUTOR,
|
||||
broadcastMessage,
|
||||
@@ -209,15 +213,27 @@ public class StudioServiceImpl extends ServiceImpl<StudioMapper, Studio> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<Studio> studioList(PageVO pageVO, Integer recommend, String status) {
|
||||
public IPage<StudioVO> studioList(PageVO pageVO, Integer recommend, String status) {
|
||||
QueryWrapper queryWrapper = new QueryWrapper<Studio>()
|
||||
.eq(recommend != null, "recommend", true)
|
||||
.eq(status != null, "status", status)
|
||||
.eq(CharSequenceUtil.isNotEmpty(status), "status", status)
|
||||
.orderByDesc("create_time");
|
||||
if (UserContext.getCurrentUser() != null && UserContext.getCurrentUser().getRole().equals(UserEnums.STORE)) {
|
||||
queryWrapper.eq("store_id", UserContext.getCurrentUser().getStoreId());
|
||||
}
|
||||
return this.page(PageUtil.initPage(pageVO), queryWrapper);
|
||||
Page page = this.page(PageUtil.initPage(pageVO), queryWrapper);
|
||||
List<Studio> records = page.getRecords();
|
||||
List<StudioVO> studioVOS = new ArrayList<>();
|
||||
for (Studio record : records) {
|
||||
StudioVO studioVO = new StudioVO();
|
||||
//获取直播间信息
|
||||
BeanUtil.copyProperties(record, studioVO);
|
||||
//获取直播间商品信息
|
||||
studioVO.setCommodityList(commodityMapper.getCommodityByRoomId(studioVO.getRoomId()));
|
||||
studioVOS.add(studioVO);
|
||||
}
|
||||
page.setRecords(studioVOS);
|
||||
return page;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package cn.lili.modules.goods.serviceimpl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.lili.cache.Cache;
|
||||
import cn.lili.modules.goods.entity.dos.Wholesale;
|
||||
import cn.lili.modules.goods.mapper.WholesaleMapper;
|
||||
import cn.lili.modules.goods.service.WholesaleService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author paulG
|
||||
* @since 2022/5/24
|
||||
**/
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "{wholesale}_")
|
||||
public class WholesaleServiceImpl extends ServiceImpl<WholesaleMapper, Wholesale> implements WholesaleService {
|
||||
|
||||
@Autowired
|
||||
private Cache<List<Wholesale>> cache;
|
||||
|
||||
@Override
|
||||
@Cacheable(key = "#goodsId")
|
||||
public List<Wholesale> findByGoodsId(String goodsId) {
|
||||
LambdaQueryWrapper<Wholesale> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(Wholesale::getGoodsId, goodsId);
|
||||
return this.list(queryWrapper).stream().sorted(Comparator.comparing(Wholesale::getNum)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(key = "#goodsId")
|
||||
public Boolean removeByGoodsId(String goodsId) {
|
||||
LambdaQueryWrapper<Wholesale> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(Wholesale::getGoodsId, goodsId);
|
||||
cache.remove("{wholesale}_" + goodsId);
|
||||
return this.remove(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wholesale match(String goodsId, Integer num) {
|
||||
List<Wholesale> wholesaleList = cache.get("{wholesale}_" + goodsId);
|
||||
if (wholesaleList == null) {
|
||||
wholesaleList = this.findByGoodsId(goodsId);
|
||||
cache.put("{wholesale}_" + goodsId, wholesaleList);
|
||||
}
|
||||
List<Wholesale> matchList = wholesaleList.stream()
|
||||
.filter(wholesale -> wholesale.getNum() <= num)
|
||||
.collect(Collectors.toList());
|
||||
if (CollUtil.isNotEmpty(matchList)) {
|
||||
return matchList.get(matchList.size() - 1);
|
||||
} else if (CollUtil.isNotEmpty(wholesaleList) && CollUtil.isEmpty(matchList)) {
|
||||
return wholesaleList.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package cn.lili.modules.goods.sku;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.modules.goods.entity.dos.Goods;
|
||||
import cn.lili.modules.goods.entity.dos.GoodsSku;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author paulG
|
||||
* @since 2022/5/20
|
||||
**/
|
||||
@Component
|
||||
public class GoodsSkuBuilder {
|
||||
|
||||
|
||||
private static final String IMAGES_KEY = "images";
|
||||
|
||||
|
||||
/**
|
||||
* 构建商品sku
|
||||
*
|
||||
* @param goods 商品
|
||||
* @param skuInfo sku信息列表
|
||||
* @param goodsOperationDTO 商品操作信息(如需处理额外信息传递,不需可传空)
|
||||
* @return 商品sku
|
||||
*/
|
||||
public static GoodsSku build(Goods goods, Map<String, Object> skuInfo, GoodsOperationDTO goodsOperationDTO) {
|
||||
GoodsSku goodsSku = new GoodsSku(goods);
|
||||
builderSingle(goodsSku, skuInfo, goodsOperationDTO);
|
||||
return goodsSku;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量构建商品sku
|
||||
*
|
||||
* @param goods 商品
|
||||
* @param goodsOperationDTO 商品操作信息
|
||||
* @return 商品sku
|
||||
*/
|
||||
public static List<GoodsSku> buildBatch(Goods goods, GoodsOperationDTO goodsOperationDTO) {
|
||||
return builderBatch(goods, goodsOperationDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从已有的商品sku中构建商品sku
|
||||
*
|
||||
* @param goodsSku 原商品sku
|
||||
* @param skuInfo sku信息列表
|
||||
* @param goodsOperationDTO 商品操作信息(如需处理额外信息传递,不需可传空)
|
||||
* @return 商品sku
|
||||
*/
|
||||
public static GoodsSku build(GoodsSku goodsSku, Map<String, Object> skuInfo, GoodsOperationDTO goodsOperationDTO) {
|
||||
builderSingle(goodsSku, skuInfo, goodsOperationDTO);
|
||||
return goodsSku;
|
||||
}
|
||||
|
||||
private static void builderSingle(GoodsSku goodsSku, Map<String, Object> skuInfo, GoodsOperationDTO goodsOperationDTO) {
|
||||
Assert.notNull(goodsSku, "goodsSku不能为空");
|
||||
Assert.notEmpty(skuInfo, "skuInfo不能为空");
|
||||
//规格简短信息
|
||||
StringBuilder simpleSpecs = new StringBuilder();
|
||||
//商品名称
|
||||
StringBuilder goodsName = new StringBuilder(goodsOperationDTO.getGoodsName());
|
||||
//规格值
|
||||
Map<String, Object> specMap = new HashMap<>(16);
|
||||
|
||||
// 原始规格项
|
||||
String[] ignoreOriginKeys = {"id", "sn", "cost", "price", "quantity", "weight"};
|
||||
//获取规格信息
|
||||
for (Map.Entry<String, Object> spec : skuInfo.entrySet()) {
|
||||
//保存新增规格信息
|
||||
if (!CollUtil.contains(Arrays.asList(ignoreOriginKeys), spec.getKey()) && spec.getValue() != null) {
|
||||
specMap.put(spec.getKey(), spec.getValue());
|
||||
if (!spec.getKey().equals(IMAGES_KEY)) {
|
||||
//设置商品名称
|
||||
goodsName.append(" ").append(spec.getValue());
|
||||
//规格简短信息
|
||||
simpleSpecs.append(" ").append(spec.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
//设置规格信息
|
||||
goodsSku.setGoodsName(goodsName.toString());
|
||||
|
||||
|
||||
//规格信息
|
||||
goodsSku.setId(Convert.toStr(skuInfo.get("id"), ""));
|
||||
goodsSku.setSn(Convert.toStr(skuInfo.get("sn")));
|
||||
goodsSku.setWeight(Convert.toDouble(skuInfo.get("weight"), 0D));
|
||||
goodsSku.setPrice(Convert.toDouble(skuInfo.get("price"), 0D));
|
||||
goodsSku.setCost(Convert.toDouble(skuInfo.get("cost"), 0D));
|
||||
goodsSku.setQuantity(Convert.toInt(skuInfo.get("quantity"), 0));
|
||||
goodsSku.setSpecs(JSONUtil.toJsonStr(specMap));
|
||||
goodsSku.setSimpleSpecs(simpleSpecs.toString());
|
||||
}
|
||||
|
||||
private static List<GoodsSku> builderBatch(Goods goods, GoodsOperationDTO goodsOperationDTO) {
|
||||
Assert.notEmpty(goodsOperationDTO.getSkuList(), "goodsOperationDTO.getSkuList()不能为空");
|
||||
Assert.notNull(goods, "goods不能为空");
|
||||
List<GoodsSku> goodsSkus = new ArrayList<>();
|
||||
for (Map<String, Object> skuInfo : goodsOperationDTO.getSkuList()) {
|
||||
GoodsSku goodsSku = new GoodsSku(goods);
|
||||
builderSingle(goodsSku, skuInfo, goodsOperationDTO);
|
||||
goodsSkus.add(goodsSku);
|
||||
}
|
||||
return goodsSkus;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package cn.lili.modules.goods.sku.render;
|
||||
|
||||
import cn.lili.modules.goods.entity.dos.GoodsSku;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 根据商品销售模型渲染商品sku
|
||||
*
|
||||
* @author paulG
|
||||
* @since 2022/5/20
|
||||
**/
|
||||
public interface SalesModelRender {
|
||||
|
||||
|
||||
String getSalesMode();
|
||||
|
||||
void renderSingle(GoodsSku goodsSku, GoodsOperationDTO goodsOperationDTO);
|
||||
|
||||
void renderBatch(List<GoodsSku> goodsSkus, GoodsOperationDTO goodsOperationDTO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package cn.lili.modules.goods.sku.render.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.modules.goods.entity.dos.GoodsSku;
|
||||
import cn.lili.modules.goods.entity.dos.Wholesale;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
|
||||
import cn.lili.modules.goods.entity.dto.WholesaleDTO;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum;
|
||||
import cn.lili.modules.goods.service.WholesaleService;
|
||||
import cn.lili.modules.goods.sku.render.SalesModelRender;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author paulG
|
||||
* @since 2022/5/24
|
||||
**/
|
||||
@Component
|
||||
public class WholesaleSaleModelRenderImpl implements SalesModelRender {
|
||||
/**
|
||||
* 批发商品
|
||||
*/
|
||||
@Autowired
|
||||
private WholesaleService wholesaleService;
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void renderSingle(GoodsSku goodsSku, GoodsOperationDTO goodsOperationDTO) {
|
||||
Assert.notEmpty(goodsOperationDTO.getWholesaleList(), "批发规则不能为空");
|
||||
this.checkWholesaleList(goodsOperationDTO.getWholesaleList(), goodsSku);
|
||||
List<Wholesale> collect = goodsOperationDTO.getWholesaleList().stream().sorted(Comparator.comparing(Wholesale::getPrice)).collect(Collectors.toList());
|
||||
wholesaleService.removeByGoodsId(goodsSku.getGoodsId());
|
||||
wholesaleService.saveOrUpdateBatch(collect);
|
||||
goodsSku.setPrice(collect.get(0).getPrice());
|
||||
goodsSku.setCost(collect.get(0).getPrice());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void renderBatch(List<GoodsSku> goodsSkus, GoodsOperationDTO goodsOperationDTO) {
|
||||
Assert.notEmpty(goodsOperationDTO.getWholesaleList(), "批发规则不能为空");
|
||||
this.checkWholesaleList(goodsOperationDTO.getWholesaleList(), goodsSkus.get(0));
|
||||
List<Wholesale> collect = goodsOperationDTO.getWholesaleList().stream().sorted(Comparator.comparing(Wholesale::getPrice)).collect(Collectors.toList());
|
||||
for (GoodsSku skus : goodsSkus) {
|
||||
skus.setPrice(collect.get(0).getPrice());
|
||||
skus.setCost(collect.get(0).getPrice());
|
||||
}
|
||||
wholesaleService.removeByGoodsId(goodsSkus.get(0).getGoodsId());
|
||||
wholesaleService.saveOrUpdateBatch(collect);
|
||||
}
|
||||
|
||||
private void checkWholesaleList(List<WholesaleDTO> wholesaleList, GoodsSku goodsSku) {
|
||||
if (CollUtil.isEmpty(wholesaleList)) {
|
||||
throw new ServiceException(ResultCode.MUST_HAVE_SALES_MODEL);
|
||||
}
|
||||
for (WholesaleDTO wholesaleDTO : wholesaleList) {
|
||||
if (wholesaleDTO.getPrice() == null || wholesaleDTO.getPrice() <= 0 || wholesaleDTO.getNum() == null || wholesaleDTO.getNum() <= 0) {
|
||||
throw new ServiceException(ResultCode.HAVE_INVALID_SALES_MODEL);
|
||||
}
|
||||
if (CharSequenceUtil.isEmpty(wholesaleDTO.getGoodsId())) {
|
||||
wholesaleDTO.setGoodsId(goodsSku.getGoodsId());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSalesMode() {
|
||||
return GoodsSalesModeEnum.WHOLESALE.name();
|
||||
}
|
||||
}
|
||||
@@ -42,4 +42,8 @@ public class MemberSign extends BaseIdEntity {
|
||||
@ApiModelProperty(value = "连续签到天数")
|
||||
private Integer signDay;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "签到日 为数字 从现在减去19700101 的日期")
|
||||
private Integer day;
|
||||
|
||||
}
|
||||
|
||||
@@ -21,9 +21,8 @@ import java.util.Date;
|
||||
@Data
|
||||
public class ManagerMemberEditDTO {
|
||||
|
||||
@ApiModelProperty(value = "会员用户名,用户名不能进行修改", required = true)
|
||||
@NotNull(message = "会员用户名不能为空")
|
||||
private String username;
|
||||
@NotNull(message = "用户ID不能为空")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty(value = "会员密码")
|
||||
private String password;
|
||||
@@ -45,7 +44,7 @@ public class ManagerMemberEditDTO {
|
||||
private Integer sex;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
@ApiModelProperty(value = "会员生日")
|
||||
private Date birthday;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import lombok.Data;
|
||||
@Data
|
||||
public class EvaluationNumberVO {
|
||||
|
||||
@ApiModelProperty(value = "全部商品")
|
||||
@ApiModelProperty(value = "全部评价")
|
||||
private Integer all;
|
||||
|
||||
@ApiModelProperty(value = "好评数量")
|
||||
|
||||
@@ -18,17 +18,6 @@ import java.util.List;
|
||||
* @since 2020-02-25 14:10:16
|
||||
*/
|
||||
public interface FootprintMapper extends BaseMapper<FootPrint> {
|
||||
|
||||
/**
|
||||
* 获取用户足迹的SkuId分页
|
||||
*
|
||||
* @param page 分页
|
||||
* @param queryWrapper 查询条件
|
||||
* @return 用户足迹的SkuId分页
|
||||
*/
|
||||
@Select("select sku_id from li_foot_print ${ew.customSqlSegment} ")
|
||||
List<String> footprintSkuIdList(IPage<String> page, @Param(Constants.WRAPPER) Wrapper<FootPrint> queryWrapper);
|
||||
|
||||
/**
|
||||
* 删除超过100条后的记录
|
||||
*
|
||||
|
||||
@@ -38,7 +38,7 @@ public interface MemberEvaluationMapper extends BaseMapper<MemberEvaluation> {
|
||||
* @param goodsId 商品ID
|
||||
* @return 会员评价
|
||||
*/
|
||||
@Select("select grade,count(1) as num from li_member_evaluation Where goods_id=#{goodsId} and status='OPEN' GROUP BY grade")
|
||||
@Select("select grade,count(1) as num from li_member_evaluation Where goods_id=#{goodsId} and status='OPEN' and delete_flag = false GROUP BY grade")
|
||||
List<Map<String, Object>> getEvaluationNumber(String goodsId);
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,7 @@ package cn.lili.modules.member.service;
|
||||
import cn.lili.common.vo.PageVO;
|
||||
import cn.lili.modules.member.entity.dos.FootPrint;
|
||||
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
@@ -44,7 +45,7 @@ public interface FootprintService extends IService<FootPrint> {
|
||||
* @param pageVO 分页
|
||||
* @return 会员浏览历史列表
|
||||
*/
|
||||
List<EsGoodsIndex> footPrintPage(PageVO pageVO);
|
||||
IPage<EsGoodsIndex> footPrintPage(PageVO pageVO);
|
||||
|
||||
/**
|
||||
* 获取当前会员的浏览记录数量
|
||||
|
||||
@@ -25,6 +25,11 @@ import java.util.Map;
|
||||
*/
|
||||
public interface MemberService extends IService<Member> {
|
||||
|
||||
/**
|
||||
* 默认密码
|
||||
*/
|
||||
static String DEFAULT_PASSWORD = "111111";
|
||||
|
||||
/**
|
||||
* 获取当前登录的用户信息
|
||||
*
|
||||
@@ -92,6 +97,29 @@ public interface MemberService extends IService<Member> {
|
||||
*/
|
||||
Member modifyPass(String memberId, String oldPassword, String newPassword);
|
||||
|
||||
/**
|
||||
* 是否可以初始化密码
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean canInitPass();
|
||||
|
||||
/**
|
||||
* 初始化密码
|
||||
*
|
||||
* @param password 密码
|
||||
* @return 操作结果
|
||||
*/
|
||||
void initPass(String password);
|
||||
|
||||
/**
|
||||
* 注销账号
|
||||
*
|
||||
* @param password 密码
|
||||
* @return 操作结果
|
||||
*/
|
||||
void cancellation(String password);
|
||||
|
||||
/**
|
||||
* 注册会员
|
||||
*
|
||||
@@ -257,6 +285,7 @@ public interface MemberService extends IService<Member> {
|
||||
|
||||
/**
|
||||
* 获取用户VO
|
||||
*
|
||||
* @param id 会员id
|
||||
* @return 用户VO
|
||||
*/
|
||||
|
||||
@@ -9,16 +9,18 @@ import cn.lili.modules.search.entity.dos.EsGoodsIndex;
|
||||
import cn.lili.modules.search.service.EsGoodsSearchService;
|
||||
import cn.lili.mybatis.util.PageUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 会员浏览历史业务层实现
|
||||
@@ -29,9 +31,7 @@ import java.util.Objects;
|
||||
@Service
|
||||
public class FootprintServiceImpl extends ServiceImpl<FootprintMapper, FootPrint> implements FootprintService {
|
||||
|
||||
/**
|
||||
* es商品业务层
|
||||
*/
|
||||
|
||||
@Autowired
|
||||
private EsGoodsSearchService esGoodsSearchService;
|
||||
|
||||
@@ -74,20 +74,33 @@ public class FootprintServiceImpl extends ServiceImpl<FootprintMapper, FootPrint
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EsGoodsIndex> footPrintPage(PageVO pageVO) {
|
||||
public IPage<EsGoodsIndex> footPrintPage(PageVO pageVO) {
|
||||
|
||||
LambdaQueryWrapper<FootPrint> lambdaQueryWrapper = Wrappers.lambdaQuery();
|
||||
lambdaQueryWrapper.eq(FootPrint::getMemberId, UserContext.getCurrentUser().getId());
|
||||
lambdaQueryWrapper.eq(FootPrint::getDeleteFlag, false);
|
||||
lambdaQueryWrapper.orderByDesc(FootPrint::getUpdateTime);
|
||||
List<String> skuIdList = this.baseMapper.footprintSkuIdList(PageUtil.initPage(pageVO), lambdaQueryWrapper);
|
||||
if (!skuIdList.isEmpty()) {
|
||||
List<EsGoodsIndex> list = esGoodsSearchService.getEsGoodsBySkuIds(skuIdList);
|
||||
lambdaQueryWrapper.orderByDesc(FootPrint::getCreateTime);
|
||||
IPage<FootPrint> footPrintPages = this.page(PageUtil.initPage(pageVO), lambdaQueryWrapper);
|
||||
|
||||
|
||||
//定义结果
|
||||
IPage<EsGoodsIndex> esGoodsIndexIPage = new Page<>();
|
||||
|
||||
if (footPrintPages.getRecords() == null || footPrintPages.getRecords().isEmpty()) {
|
||||
return esGoodsIndexIPage;
|
||||
} else {
|
||||
List<EsGoodsIndex> list = esGoodsSearchService.getEsGoodsBySkuIds(
|
||||
footPrintPages.getRecords().stream().map(FootPrint::getSkuId).collect(Collectors.toList()));
|
||||
//去除为空的商品数据
|
||||
list.removeIf(Objects::isNull);
|
||||
return list;
|
||||
|
||||
esGoodsIndexIPage.setPages(footPrintPages.getPages());
|
||||
esGoodsIndexIPage.setRecords(list);
|
||||
esGoodsIndexIPage.setTotal(footPrintPages.getTotal());
|
||||
esGoodsIndexIPage.setSize(footPrintPages.getSize());
|
||||
esGoodsIndexIPage.setCurrent(footPrintPages.getCurrent());
|
||||
return esGoodsIndexIPage;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -113,13 +113,15 @@ public class MemberEvaluationServiceImpl extends ServiceImpl<MemberEvaluationMap
|
||||
Order order = orderService.getBySn(orderItem.getOrderSn());
|
||||
//检测是否可以添加会员评价
|
||||
Member member;
|
||||
|
||||
checkMemberEvaluation(orderItem, order);
|
||||
|
||||
if (Boolean.TRUE.equals(isSelf)) {
|
||||
checkMemberEvaluation(orderItem, order);
|
||||
//获取用户信息 非自己评价时,读取数据库
|
||||
member = memberService.getById(order.getMemberId());
|
||||
} else {
|
||||
//自我评价商品时,获取当前登录用户信息
|
||||
member = memberService.getUserInfo();
|
||||
} else {
|
||||
//获取用户信息 非自己评价时,读取数据库
|
||||
member = memberService.getById(order.getMemberId());
|
||||
}
|
||||
//获取商品信息
|
||||
GoodsSku goodsSku = goodsSkuService.getGoodsSkuByIdFromCache(memberEvaluationDTO.getSkuId());
|
||||
|
||||
@@ -5,9 +5,11 @@ import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.lili.cache.Cache;
|
||||
import cn.lili.cache.CachePrefix;
|
||||
import cn.lili.common.aop.annotation.DemoSite;
|
||||
import cn.lili.common.context.ThreadContextHolder;
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.enums.SwitchEnum;
|
||||
import cn.lili.common.event.TransactionCommitSendMQEvent;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.properties.RocketmqCustomProperties;
|
||||
import cn.lili.common.security.AuthUser;
|
||||
@@ -15,11 +17,7 @@ import cn.lili.common.security.context.UserContext;
|
||||
import cn.lili.common.security.enums.UserEnums;
|
||||
import cn.lili.common.security.token.Token;
|
||||
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.utils.*;
|
||||
import cn.lili.common.vo.PageVO;
|
||||
import cn.lili.modules.connect.config.ConnectAuthEnum;
|
||||
import cn.lili.modules.connect.entity.Connect;
|
||||
@@ -39,7 +37,6 @@ import cn.lili.modules.store.entity.dos.Store;
|
||||
import cn.lili.modules.store.entity.enums.StoreStatusEnum;
|
||||
import cn.lili.modules.store.service.StoreService;
|
||||
import cn.lili.mybatis.util.PageUtil;
|
||||
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
|
||||
import cn.lili.rocketmq.tags.MemberTagsEnum;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
@@ -47,8 +44,8 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
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.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -92,11 +89,9 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
*/
|
||||
@Autowired
|
||||
private RocketmqCustomProperties rocketmqCustomProperties;
|
||||
/**
|
||||
* RocketMQ
|
||||
*/
|
||||
|
||||
@Autowired
|
||||
private RocketMQTemplate rocketMQTemplate;
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
/**
|
||||
* 缓存
|
||||
*/
|
||||
@@ -121,12 +116,17 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public Member findByMobile(String mobile) {
|
||||
public boolean findByMobile(String uuid, String mobile) {
|
||||
QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("mobile", mobile);
|
||||
return this.baseMapper.selectOne(queryWrapper);
|
||||
}
|
||||
Member member = this.baseMapper.selectOne(queryWrapper);
|
||||
if (member == null) {
|
||||
throw new ServiceException(ResultCode.USER_NOT_PHONE);
|
||||
}
|
||||
cache.put(CachePrefix.FIND_MOBILE + uuid, mobile, 300L);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token usernameLogin(String username, String password) {
|
||||
@@ -181,6 +181,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Token autoRegister(ConnectAuthUser authUser) {
|
||||
|
||||
if (CharSequenceUtil.isEmpty(authUser.getNickname())) {
|
||||
@@ -194,11 +195,12 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
Member member = new Member(username, UuidUtils.getUUID(), authUser.getAvatar(), authUser.getNickname(),
|
||||
authUser.getGender() != null ? Convert.toInt(authUser.getGender().getCode()) : 0);
|
||||
registerHandler(member);
|
||||
member.setPassword(DEFAULT_PASSWORD);
|
||||
//绑定登录方式
|
||||
loginBindUser(member, authUser.getUuid(), authUser.getSource());
|
||||
return memberTokenGenerate.createToken(member, false);
|
||||
} catch (ServiceException e) {
|
||||
log.error("自动注册服务泡出异常:", e);
|
||||
log.error("自动注册服务抛出异常:", e);
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("自动注册异常:", e);
|
||||
@@ -223,6 +225,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Token mobilePhoneLogin(String mobilePhone) {
|
||||
QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("mobile", mobilePhone);
|
||||
@@ -241,12 +244,13 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
*
|
||||
* @param member
|
||||
*/
|
||||
private void registerHandler(Member member) {
|
||||
@Transactional
|
||||
public 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());
|
||||
// 发送会员注册信息
|
||||
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("new member register", rocketmqCustomProperties.getMemberTopic(), MemberTagsEnum.MEMBER_REGISTER.name(), member));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -261,8 +265,13 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public Member modifyPass(String memberId, String oldPassword, String newPassword) {
|
||||
Member member = this.getById(memberId);
|
||||
@DemoSite
|
||||
public Member modifyPass(String oldPassword, String newPassword) {
|
||||
AuthUser tokenUser = UserContext.getCurrentUser();
|
||||
if (tokenUser == null) {
|
||||
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
|
||||
}
|
||||
Member member = this.getById(tokenUser.getId());
|
||||
//判断旧密码输入是否正确
|
||||
if (!new BCryptPasswordEncoder().matches(oldPassword, member.getPassword())) {
|
||||
throw new ServiceException(ResultCode.USER_OLD_PASSWORD_ERROR);
|
||||
@@ -276,6 +285,65 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInitPass() {
|
||||
AuthUser tokenUser = UserContext.getCurrentUser();
|
||||
if (tokenUser == null) {
|
||||
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
|
||||
}
|
||||
Member member = this.getById(tokenUser.getId());
|
||||
return member.getPassword().equals(DEFAULT_PASSWORD);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initPass(String password) {
|
||||
AuthUser tokenUser = UserContext.getCurrentUser();
|
||||
if (tokenUser == null) {
|
||||
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
|
||||
}
|
||||
Member member = this.getById(tokenUser.getId());
|
||||
if (member.getPassword().equals(DEFAULT_PASSWORD)) {
|
||||
//修改会员密码
|
||||
LambdaUpdateWrapper<Member> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
|
||||
lambdaUpdateWrapper.eq(Member::getId, member.getId());
|
||||
lambdaUpdateWrapper.set(Member::getPassword, new BCryptPasswordEncoder().encode(password));
|
||||
this.update(lambdaUpdateWrapper);
|
||||
}
|
||||
throw new ServiceException(ResultCode.UNINITIALIZED_PASSWORD);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancellation(String password) {
|
||||
|
||||
AuthUser tokenUser = UserContext.getCurrentUser();
|
||||
if (tokenUser == null) {
|
||||
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
|
||||
}
|
||||
Member member = this.getById(tokenUser.getId());
|
||||
if (member.getPassword().equals(new BCryptPasswordEncoder().encode(password))) {
|
||||
//删除联合登录
|
||||
connectService.deleteByMemberId(member.getId());
|
||||
//混淆用户信息
|
||||
this.confusionMember(member);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 混淆之前的会员信息
|
||||
*
|
||||
* @param member
|
||||
*/
|
||||
private void confusionMember(Member member) {
|
||||
member.setUsername(UuidUtils.getUUID());
|
||||
member.setMobile(UuidUtils.getUUID() + member.getMobile());
|
||||
member.setNickName("用户已注销");
|
||||
member.setDisabled(false);
|
||||
this.updateById(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Token register(String userName, String password, String mobilePhone) {
|
||||
//检测会员信息
|
||||
checkMember(userName, mobilePhone);
|
||||
@@ -283,8 +351,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
Member member = new Member(userName, new BCryptPasswordEncoder().encode(password), mobilePhone);
|
||||
//注册成功后用户自动登录
|
||||
registerHandler(member);
|
||||
Token token = memberTokenGenerate.createToken(member, false);
|
||||
return token;
|
||||
return memberTokenGenerate.createToken(member, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -321,6 +388,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Member addMember(MemberAddDTO memberAddDTO) {
|
||||
|
||||
//检测会员信息
|
||||
@@ -334,21 +402,16 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
|
||||
@Override
|
||||
public Member updateMember(ManagerMemberEditDTO managerMemberEditDTO) {
|
||||
//判断是否用户登录并且会员ID为当前登录会员ID
|
||||
AuthUser tokenUser = UserContext.getCurrentUser();
|
||||
if (tokenUser == null) {
|
||||
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
|
||||
}
|
||||
//过滤会员昵称敏感词
|
||||
if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(managerMemberEditDTO.getNickName())) {
|
||||
if (StringUtils.isNotBlank(managerMemberEditDTO.getNickName())) {
|
||||
managerMemberEditDTO.setNickName(SensitiveWordsFilter.filter(managerMemberEditDTO.getNickName()));
|
||||
}
|
||||
//如果密码不为空则加密密码
|
||||
if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(managerMemberEditDTO.getPassword())) {
|
||||
if (StringUtils.isNotBlank(managerMemberEditDTO.getPassword())) {
|
||||
managerMemberEditDTO.setPassword(new BCryptPasswordEncoder().encode(managerMemberEditDTO.getPassword()));
|
||||
}
|
||||
//查询会员信息
|
||||
Member member = this.findByUsername(managerMemberEditDTO.getUsername());
|
||||
Member member = this.getById(managerMemberEditDTO.getId());
|
||||
//传递修改会员信息
|
||||
BeanUtil.copyProperties(managerMemberEditDTO, member);
|
||||
this.updateById(member);
|
||||
@@ -401,8 +464,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
memberPointMessage.setPoint(point);
|
||||
memberPointMessage.setType(type);
|
||||
memberPointMessage.setMemberId(memberId);
|
||||
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_POINT_CHANGE.name();
|
||||
rocketMQTemplate.asyncSend(destination, memberPointMessage, RocketmqSendCallbackBuilder.commonCallback());
|
||||
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("update member point", rocketmqCustomProperties.getMemberTopic(), MemberTagsEnum.MEMBER_POINT_CHANGE.name(), memberPointMessage));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -426,10 +488,10 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
* @param mobilePhone 手机号
|
||||
* @return 会员
|
||||
*/
|
||||
private Long findMember(String userName,String mobilePhone) {
|
||||
private Long findMember(String mobilePhone, String userName) {
|
||||
QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("mobile", mobilePhone)
|
||||
.eq("username", userName);
|
||||
.or().eq("username", userName);
|
||||
return this.baseMapper.selectCount(queryWrapper);
|
||||
}
|
||||
|
||||
@@ -579,31 +641,6 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateHaveShop(Boolean haveStore, String storeId, List<String> memberIds) {
|
||||
List<Member> members = this.baseMapper.selectBatchIds(memberIds);
|
||||
if (members.size() > 0) {
|
||||
members.forEach(member -> {
|
||||
member.setHaveStore(haveStore);
|
||||
if (haveStore) {
|
||||
member.setStoreId(storeId);
|
||||
} else {
|
||||
member.setStoreId(null);
|
||||
}
|
||||
});
|
||||
this.updateBatchById(members);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetPassword(List<String> ids) {
|
||||
String password = new BCryptPasswordEncoder().encode(StringUtils.md5("123456"));
|
||||
LambdaUpdateWrapper<Member> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
|
||||
lambdaUpdateWrapper.in(Member::getId, ids);
|
||||
lambdaUpdateWrapper.set(Member::getPassword, password);
|
||||
this.update(lambdaUpdateWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有会员的手机号
|
||||
*
|
||||
@@ -641,9 +678,8 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||
*/
|
||||
private void checkMember(String userName, String mobilePhone) {
|
||||
//判断手机号是否存在
|
||||
if (findMember(userName, mobilePhone) > 0) {
|
||||
if (findMember(mobilePhone, userName) > 0) {
|
||||
throw new ServiceException(ResultCode.USER_EXIST);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -77,8 +77,8 @@ public class MemberSignServiceImpl extends ServiceImpl<MemberSignMapper, MemberS
|
||||
} else {
|
||||
memberSign.setSignDay(1);
|
||||
}
|
||||
//手动写入创建时间,以保证唯一索引生效
|
||||
memberSign.setCreateTime(DateUtil.getCurrentDayEndTime());
|
||||
|
||||
memberSign.setDay(DateUtil.getDayOfStart().intValue());
|
||||
try {
|
||||
this.baseMapper.insert(memberSign);
|
||||
//签到成功后发送消息赠送积分
|
||||
|
||||
@@ -36,7 +36,7 @@ public class StoreCollectionServiceImpl extends ServiceImpl<StoreCollectionMappe
|
||||
|
||||
@Override
|
||||
public IPage<StoreCollectionVO> storeCollection(PageVO pageVo) {
|
||||
QueryWrapper<StoreCollectionVO> queryWrapper = new QueryWrapper();
|
||||
QueryWrapper<StoreCollectionVO> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("sc.member_id", UserContext.getCurrentUser().getId());
|
||||
queryWrapper.orderByDesc("sc.create_time");
|
||||
return this.baseMapper.storeCollectionVOList(PageUtil.initPage(pageVo), queryWrapper);
|
||||
@@ -44,10 +44,10 @@ public class StoreCollectionServiceImpl extends ServiceImpl<StoreCollectionMappe
|
||||
|
||||
@Override
|
||||
public boolean isCollection(String storeId) {
|
||||
QueryWrapper<StoreCollection> queryWrapper = new QueryWrapper();
|
||||
QueryWrapper<StoreCollection> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("member_id", UserContext.getCurrentUser().getId());
|
||||
queryWrapper.eq("store_id", storeId);
|
||||
return Optional.ofNullable(this.getOne(queryWrapper)).isPresent();
|
||||
return Optional.ofNullable(this.getOne(queryWrapper, false)).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,7 +67,7 @@ public class StoreCollectionServiceImpl extends ServiceImpl<StoreCollectionMappe
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean deleteStoreCollection(String storeId) {
|
||||
QueryWrapper<StoreCollection> queryWrapper = new QueryWrapper();
|
||||
QueryWrapper<StoreCollection> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("member_id", UserContext.getCurrentUser().getId());
|
||||
queryWrapper.eq("store_id", storeId);
|
||||
storeService.updateStoreCollectionNum(new CollectionDTO(storeId, -1));
|
||||
|
||||
@@ -37,7 +37,7 @@ public enum NoticeMessageParameterEnum {
|
||||
*/
|
||||
CANCEL_REASON("cancel_reason", "取消原因"),
|
||||
/**
|
||||
* 取消原因
|
||||
* 金额
|
||||
*/
|
||||
PRICE("price", "金额");
|
||||
|
||||
|
||||
@@ -126,8 +126,9 @@ public class AfterSaleServiceImpl extends ServiceImpl<AfterSaleMapper, AfterSale
|
||||
//获取订单货物判断是否可申请售后
|
||||
OrderItem orderItem = orderItemService.getBySn(sn);
|
||||
|
||||
//未申请售后订单货物才能进行申请
|
||||
if (!orderItem.getAfterSaleStatus().equals(OrderItemAfterSaleStatusEnum.NOT_APPLIED.name())) {
|
||||
//未申请售后订单货物或部分售后才能进行申请
|
||||
if (!orderItem.getAfterSaleStatus().equals(OrderItemAfterSaleStatusEnum.NOT_APPLIED.name())
|
||||
&& !orderItem.getAfterSaleStatus().equals(OrderItemAfterSaleStatusEnum.PART_AFTER_SALE.name())) {
|
||||
throw new ServiceException(ResultCode.AFTER_SALES_BAN);
|
||||
}
|
||||
|
||||
@@ -268,8 +269,8 @@ public class AfterSaleServiceImpl extends ServiceImpl<AfterSaleMapper, AfterSale
|
||||
|
||||
//根据售后单号获取售后单
|
||||
AfterSale afterSale = OperationalJudgment.judgment(this.getBySn(afterSaleSn));
|
||||
|
||||
return logisticsService.getLogistic(afterSale.getMLogisticsCode(), afterSale.getMLogisticsNo());
|
||||
String str=storeDetailService.getStoreDetail(afterSale.getStoreId()).getSalesConsigneeMobile();
|
||||
return logisticsService.getLogistic(afterSale.getMLogisticsCode(), afterSale.getMLogisticsNo(), str.substring(str.length()-4));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -160,4 +160,9 @@ public class TradeDTO implements Serializable {
|
||||
}
|
||||
return skuList;
|
||||
}
|
||||
|
||||
public void removeCoupon() {
|
||||
this.canUseCoupons = new ArrayList<>();
|
||||
this.cantUseCoupons = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import cn.lili.modules.order.cart.entity.enums.CartTypeEnum;
|
||||
import cn.lili.modules.promotion.tools.PromotionTools;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
@@ -19,6 +20,7 @@ import java.util.Map;
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class CartSkuVO extends CartBase implements Serializable {
|
||||
|
||||
|
||||
@@ -117,4 +119,8 @@ public class CartSkuVO extends CartBase implements Serializable {
|
||||
public Map<String, Object> getPromotionMap() {
|
||||
return PromotionTools.filterInvalidPromotionsMap(this.promotionMap);
|
||||
}
|
||||
|
||||
public Map<String, Object> getNotFilterPromotionMap() {
|
||||
return this.promotionMap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.lili.modules.order.cart.render.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
@@ -7,10 +8,14 @@ import cn.lili.common.enums.PromotionTypeEnum;
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.security.context.UserContext;
|
||||
import cn.lili.common.utils.CurrencyUtil;
|
||||
import cn.lili.modules.goods.entity.dos.GoodsSku;
|
||||
import cn.lili.modules.goods.entity.dos.Wholesale;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
|
||||
import cn.lili.modules.goods.service.GoodsSkuService;
|
||||
import cn.lili.modules.goods.service.WholesaleService;
|
||||
import cn.lili.modules.member.entity.dos.Member;
|
||||
import cn.lili.modules.member.service.MemberService;
|
||||
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
|
||||
@@ -26,6 +31,7 @@ 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.vos.CouponVO;
|
||||
import cn.lili.modules.promotion.service.PromotionGoodsService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -55,6 +61,14 @@ public class CheckDataRender implements CartRenderStep {
|
||||
@Autowired
|
||||
private MemberService memberService;
|
||||
|
||||
@Autowired
|
||||
private WholesaleService wholesaleService;
|
||||
|
||||
/**
|
||||
* 商品索引
|
||||
*/
|
||||
@Autowired
|
||||
private PromotionGoodsService promotionGoodsService;
|
||||
|
||||
@Override
|
||||
public RenderStepEnums step() {
|
||||
@@ -69,6 +83,7 @@ public class CheckDataRender implements CartRenderStep {
|
||||
//校验商品有效性
|
||||
checkData(tradeDTO);
|
||||
|
||||
preSaleModel(tradeDTO);
|
||||
//店铺分组数据初始化
|
||||
groupStore(tradeDTO);
|
||||
|
||||
@@ -92,7 +107,7 @@ public class CheckDataRender implements CartRenderStep {
|
||||
//缓存中的商品信息
|
||||
GoodsSku dataSku = goodsSkuService.getGoodsSkuByIdFromCache(cartSkuVO.getGoodsSku().getId());
|
||||
//商品有效性判定
|
||||
if (dataSku == null || dataSku.getUpdateTime().before(cartSkuVO.getGoodsSku().getUpdateTime())) {
|
||||
if (dataSku == null || dataSku.getCreateTime().after(cartSkuVO.getGoodsSku().getCreateTime())) {
|
||||
//设置购物车未选中
|
||||
cartSkuVO.setChecked(false);
|
||||
//设置购物车此sku商品已失效
|
||||
@@ -118,6 +133,17 @@ public class CheckDataRender implements CartRenderStep {
|
||||
//设置失效消息
|
||||
cartSkuVO.setErrorMessage("商品库存不足,现有库存数量[" + dataSku.getQuantity() + "]");
|
||||
}
|
||||
//如果存在商品促销活动,则判定商品促销状态
|
||||
if (!cartSkuVO.getCartType().equals(CartTypeEnum.POINTS) && (CollUtil.isNotEmpty(cartSkuVO.getNotFilterPromotionMap()) || Boolean.TRUE.equals(cartSkuVO.getGoodsSku().getPromotionFlag()))) {
|
||||
//获取当前最新的促销信息
|
||||
cartSkuVO.setPromotionMap(this.promotionGoodsService.getCurrentGoodsPromotion(cartSkuVO.getGoodsSku(), tradeDTO.getCartTypeEnum().name()));
|
||||
//设定商品价格
|
||||
Double goodsPrice = cartSkuVO.getGoodsSku().getPromotionFlag() != null && cartSkuVO.getGoodsSku().getPromotionFlag() ? cartSkuVO.getGoodsSku().getPromotionPrice() : cartSkuVO.getGoodsSku().getPrice();
|
||||
cartSkuVO.setPurchasePrice(goodsPrice);
|
||||
cartSkuVO.setUtilPrice(goodsPrice);
|
||||
cartSkuVO.setSubTotal(CurrencyUtil.mul(cartSkuVO.getPurchasePrice(), cartSkuVO.getNum()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,10 +168,12 @@ public class CheckDataRender implements CartRenderStep {
|
||||
try {
|
||||
//筛选属于当前店铺的优惠券
|
||||
storeCart.getValue().forEach(i -> i.getPromotionMap().forEach((key, 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));
|
||||
if (key.contains(PromotionTypeEnum.COUPON.name())) {
|
||||
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) {
|
||||
@@ -212,4 +240,41 @@ public class CheckDataRender implements CartRenderStep {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 商品销售模式特殊处理
|
||||
*
|
||||
* @param tradeDTO 交易信息
|
||||
*/
|
||||
private void preSaleModel(TradeDTO tradeDTO) {
|
||||
// 寻找同goods下销售模式为批发的商品
|
||||
Map<String, List<CartSkuVO>> goodsGroup = tradeDTO.getSkuList().stream().filter(i -> i.getGoodsSku().getSalesModel().equals(GoodsSalesModeEnum.WHOLESALE.name())).collect(Collectors.groupingBy(i -> i.getGoodsSku().getGoodsId()));
|
||||
if (CollUtil.isNotEmpty(goodsGroup)) {
|
||||
goodsGroup.forEach((k, v) -> {
|
||||
// 获取购买总数
|
||||
int sum = v.stream().filter(i -> Boolean.TRUE.equals(i.getChecked())).mapToInt(CartSkuVO::getNum).sum();
|
||||
int fSum = v.stream().filter(i -> Boolean.FALSE.equals(i.getChecked())).mapToInt(CartSkuVO::getNum).sum();
|
||||
// 匹配符合的批发规则
|
||||
Wholesale match = wholesaleService.match(k, sum);
|
||||
if (match != null) {
|
||||
v.forEach(i -> {
|
||||
// 将符合规则的商品设置批发价格
|
||||
if (Boolean.TRUE.equals(i.getChecked())) {
|
||||
i.setPurchasePrice(match.getPrice());
|
||||
i.getGoodsSku().setPrice(match.getPrice());
|
||||
i.getGoodsSku().setCost(match.getPrice());
|
||||
i.setUtilPrice(match.getPrice());
|
||||
i.setSubTotal(CurrencyUtil.mul(i.getPurchasePrice(), i.getNum()));
|
||||
} else {
|
||||
i.setPurchasePrice(wholesaleService.match(k, fSum).getPrice());
|
||||
i.getGoodsSku().setPrice(i.getPurchasePrice());
|
||||
i.getGoodsSku().setCost(i.getPurchasePrice());
|
||||
i.setUtilPrice(i.getPurchasePrice());
|
||||
i.setSubTotal(CurrencyUtil.mul(i.getPurchasePrice(), i.getNum()));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ 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.utils.CurrencyUtil;
|
||||
import cn.lili.modules.goods.service.CategoryService;
|
||||
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
|
||||
import cn.lili.modules.order.cart.entity.enums.CartTypeEnum;
|
||||
@@ -85,7 +86,7 @@ public class CommissionRender implements CartRenderStep {
|
||||
if (kanjiaPromotions.isPresent()) {
|
||||
JSONObject promotionsObj = JSONUtil.parseObj(kanjiaPromotions.get().getValue());
|
||||
KanjiaActivityGoods kanjiaActivityGoods = JSONUtil.toBean(promotionsObj, KanjiaActivityGoods.class);
|
||||
priceDetailDTO.setSettlementPrice(kanjiaActivityGoods.getSettlementPrice());
|
||||
priceDetailDTO.setSettlementPrice(CurrencyUtil.add(kanjiaActivityGoods.getSettlementPrice(),priceDetailDTO.getBillPrice()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,7 @@ import cn.lili.modules.promotion.service.MemberCouponService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -60,8 +57,16 @@ public class CouponRender implements CartRenderStep {
|
||||
* @param tradeDTO 交易dto
|
||||
*/
|
||||
private void renderCouponRule(TradeDTO tradeDTO) {
|
||||
// 清除之前的优惠券
|
||||
tradeDTO.removeCoupon();
|
||||
|
||||
List<MemberCoupon> memberCouponList = memberCouponService.getMemberCoupons(tradeDTO.getMemberId());
|
||||
|
||||
//获取最新优惠券
|
||||
memberCouponList = memberCouponList.stream()
|
||||
.filter(item -> item.getStartTime().before(new Date()) && item.getEndTime().after(new Date()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!memberCouponList.isEmpty()) {
|
||||
this.checkMemberExistCoupon(tradeDTO, memberCouponList);
|
||||
} else {
|
||||
|
||||
@@ -15,7 +15,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* sku 运费计算
|
||||
@@ -43,31 +46,35 @@ public class SkuFreightRender implements CartRenderStep {
|
||||
if (memberAddress == null) {
|
||||
return;
|
||||
}
|
||||
//循环渲染购物车商品运费价格
|
||||
forSku:
|
||||
for (CartSkuVO cartSkuVO : cartSkuVOS) {
|
||||
//获取sku运费模版
|
||||
String freightTemplateId = cartSkuVO.getGoodsSku().getFreightTemplateId();
|
||||
//免运费则跳出运费计算
|
||||
if (Boolean.TRUE.equals(cartSkuVO.getIsFreeFreight()) || freightTemplateId == null) {
|
||||
continue;
|
||||
}
|
||||
//运费分组信息
|
||||
Map<String, List<String>> freightGroups = freightTemplateGrouping(cartSkuVOS);
|
||||
|
||||
//循环运费模版
|
||||
for (Map.Entry<String, List<String>> freightTemplateGroup : freightGroups.entrySet()) {
|
||||
|
||||
//商品id列表
|
||||
List<String> skuIds = freightTemplateGroup.getValue();
|
||||
|
||||
//当前购物车商品列表
|
||||
List<CartSkuVO> currentCartSkus = cartSkuVOS.stream().filter(item -> skuIds.contains(item.getGoodsSku().getId())).collect(Collectors.toList());
|
||||
|
||||
//寻找对应对商品运费计算模版
|
||||
FreightTemplateVO freightTemplate = freightTemplateService.getFreightTemplate(freightTemplateId);
|
||||
FreightTemplateVO freightTemplate = freightTemplateService.getFreightTemplate(freightTemplateGroup.getKey());
|
||||
if (freightTemplate != null
|
||||
&& freightTemplate.getFreightTemplateChildList() != null
|
||||
&& !freightTemplate.getFreightTemplateChildList().isEmpty()) {
|
||||
//店铺支付运费则跳过
|
||||
//店铺模版免运费则跳过
|
||||
if (freightTemplate.getPricingMethod().equals(FreightTemplateEnum.FREE.name())) {
|
||||
break;
|
||||
}
|
||||
|
||||
//运费模版
|
||||
FreightTemplateChild freightTemplateChild = null;
|
||||
|
||||
//获取市级别id
|
||||
//获取市级别id匹配运费模版
|
||||
String addressId = memberAddress.getConsigneeAddressIdPath().split(",")[1];
|
||||
//获取匹配的收货地址
|
||||
for (FreightTemplateChild templateChild : freightTemplate.getFreightTemplateChildList()) {
|
||||
//如果当前模版包含,则返回
|
||||
//模版匹配判定
|
||||
if (templateChild.getAreaId().contains(addressId)) {
|
||||
freightTemplateChild = templateChild;
|
||||
break;
|
||||
@@ -78,28 +85,97 @@ public class SkuFreightRender implements CartRenderStep {
|
||||
if (tradeDTO.getNotSupportFreight() == null) {
|
||||
tradeDTO.setNotSupportFreight(new ArrayList<>());
|
||||
}
|
||||
tradeDTO.getNotSupportFreight().add(cartSkuVO);
|
||||
continue forSku;
|
||||
tradeDTO.getNotSupportFreight().addAll(currentCartSkus);
|
||||
continue;
|
||||
}
|
||||
|
||||
//物流规则模型创立
|
||||
FreightTemplateChildDTO freightTemplateChildDTO = new FreightTemplateChildDTO(freightTemplateChild);
|
||||
|
||||
//模型写入运费模版设置的计费方式
|
||||
freightTemplateChildDTO.setPricingMethod(freightTemplate.getPricingMethod());
|
||||
|
||||
//要计算的基数 数量/重量
|
||||
Double count = (freightTemplateChildDTO.getPricingMethod().equals(FreightTemplateEnum.NUM.name())) ?
|
||||
cartSkuVO.getNum() :
|
||||
cartSkuVO.getGoodsSku().getWeight() * cartSkuVO.getNum();
|
||||
//计算运费总数
|
||||
Double count = currentCartSkus.stream().mapToDouble(item ->
|
||||
// 根据计费规则 累加计费基数
|
||||
freightTemplateChildDTO.getPricingMethod().equals(FreightTemplateEnum.NUM.name()) ?
|
||||
item.getNum().doubleValue() :
|
||||
CurrencyUtil.mul(item.getNum(), item.getGoodsSku().getWeight())
|
||||
).sum();
|
||||
|
||||
//计算运费
|
||||
Double countFreight = countFreight(count, freightTemplateChildDTO);
|
||||
|
||||
//写入SKU运费
|
||||
cartSkuVO.getPriceDetailDTO().setFreightPrice(countFreight);
|
||||
resetFreightPrice(FreightTemplateEnum.valueOf(freightTemplateChildDTO.getPricingMethod()), count, countFreight, currentCartSkus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sku运费写入
|
||||
*
|
||||
* @param freightTemplateEnum 运费计算模式
|
||||
* @param count 计费基数总数
|
||||
* @param countFreight 总运费
|
||||
* @param cartSkuVOS 与运费相关的购物车商品
|
||||
*/
|
||||
private void resetFreightPrice(FreightTemplateEnum freightTemplateEnum, Double count, Double countFreight, List<CartSkuVO> cartSkuVOS) {
|
||||
|
||||
//剩余运费 默认等于总运费
|
||||
Double surplusFreightPrice = countFreight;
|
||||
|
||||
//当前下标
|
||||
int index = 1;
|
||||
for (CartSkuVO cartSkuVO : cartSkuVOS) {
|
||||
//如果是最后一个 则将剩余运费直接赋值
|
||||
//PS: 循环中避免百分比累加不等于100%,所以最后一个运费不以比例计算,直接将剩余运费赋值
|
||||
if (index == cartSkuVOS.size()) {
|
||||
cartSkuVO.getPriceDetailDTO().setFreightPrice(surplusFreightPrice);
|
||||
break;
|
||||
}
|
||||
|
||||
Double freightPrice = freightTemplateEnum == FreightTemplateEnum.NUM ?
|
||||
CurrencyUtil.mul(countFreight, CurrencyUtil.div(cartSkuVO.getNum(), count)) :
|
||||
CurrencyUtil.mul(countFreight,
|
||||
CurrencyUtil.div(CurrencyUtil.mul(cartSkuVO.getNum(), cartSkuVO.getGoodsSku().getWeight()), count));
|
||||
|
||||
//剩余运费=总运费-当前循环的商品运费
|
||||
surplusFreightPrice = CurrencyUtil.sub(surplusFreightPrice, freightPrice);
|
||||
|
||||
cartSkuVO.getPriceDetailDTO().setFreightPrice(freightPrice);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 运费模版分组
|
||||
*
|
||||
* @param cartSkuVOS 购物车商品
|
||||
* @return map<运费模版id , List < skuid>>
|
||||
*/
|
||||
private Map<String, List<String>> freightTemplateGrouping(List<CartSkuVO> cartSkuVOS) {
|
||||
Map<String, List<String>> map = new HashMap<>();
|
||||
//循环渲染购物车商品运费价格
|
||||
for (CartSkuVO cartSkuVO : cartSkuVOS) {
|
||||
////免运费判定
|
||||
String freightTemplateId = cartSkuVO.getGoodsSku().getFreightTemplateId();
|
||||
if (Boolean.TRUE.equals(cartSkuVO.getIsFreeFreight()) || freightTemplateId == null) {
|
||||
continue;
|
||||
}
|
||||
//包含 则value值中写入sku标识,否则直接写入新的对象,key为模版id,value为new arraylist
|
||||
if (map.containsKey(freightTemplateId)) {
|
||||
map.get(freightTemplateId).add(cartSkuVO.getGoodsSku().getId());
|
||||
} else {
|
||||
List<String> skuIdsList = new ArrayList<>();
|
||||
skuIdsList.add(cartSkuVO.getGoodsSku().getId());
|
||||
map.put(freightTemplateId, skuIdsList);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 计算运费
|
||||
*
|
||||
|
||||
@@ -74,7 +74,7 @@ public class SkuPromotionRender implements CartRenderStep {
|
||||
renderBasePrice(tradeDTO);
|
||||
//渲染单品促销
|
||||
renderSkuPromotion(tradeDTO);
|
||||
|
||||
//检查促销库存
|
||||
checkPromotionQuantity(tradeDTO);
|
||||
|
||||
|
||||
@@ -186,7 +186,6 @@ public class SkuPromotionRender implements CartRenderStep {
|
||||
*/
|
||||
private void checkPromotionQuantity(TradeDTO tradeDTO) {
|
||||
for (CartSkuVO cartSkuVO : tradeDTO.getCheckedSkuList()) {
|
||||
cartSkuVO.getPromotionMap();
|
||||
List<PromotionSkuVO> joinPromotion = cartSkuVO.getPriceDetailDTO().getJoinPromotion();
|
||||
if (!joinPromotion.isEmpty()) {
|
||||
for (PromotionSkuVO promotionSkuVO : joinPromotion) {
|
||||
|
||||
@@ -95,13 +95,6 @@ public interface CartService {
|
||||
*/
|
||||
void clean();
|
||||
|
||||
/**
|
||||
* 清空购物车无效数据
|
||||
*
|
||||
* @param way 购物车类型
|
||||
*/
|
||||
void cleanChecked(CartTypeEnum way);
|
||||
|
||||
/**
|
||||
* 重新写入
|
||||
*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.lili.modules.order.cart.service;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
@@ -11,11 +12,12 @@ import cn.lili.common.security.AuthUser;
|
||||
import cn.lili.common.security.context.UserContext;
|
||||
import cn.lili.common.utils.CurrencyUtil;
|
||||
import cn.lili.modules.goods.entity.dos.GoodsSku;
|
||||
import cn.lili.modules.goods.entity.dos.Wholesale;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
|
||||
import cn.lili.modules.goods.entity.vos.GoodsVO;
|
||||
import cn.lili.modules.goods.service.GoodsService;
|
||||
import cn.lili.modules.goods.service.GoodsSkuService;
|
||||
import cn.lili.modules.goods.service.WholesaleService;
|
||||
import cn.lili.modules.member.entity.dos.Member;
|
||||
import cn.lili.modules.member.entity.dos.MemberAddress;
|
||||
import cn.lili.modules.member.service.MemberAddressService;
|
||||
@@ -32,10 +34,8 @@ 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.MemberCoupon;
|
||||
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;
|
||||
@@ -45,7 +45,6 @@ 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 lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -97,16 +96,6 @@ public class CartServiceImpl implements CartService {
|
||||
*/
|
||||
@Autowired
|
||||
private EsGoodsSearchService esGoodsSearchService;
|
||||
/**
|
||||
* 商品索引
|
||||
*/
|
||||
@Autowired
|
||||
private EsGoodsIndexService goodsIndexService;
|
||||
/**
|
||||
* ES商品
|
||||
*/
|
||||
@Autowired
|
||||
private GoodsService goodsService;
|
||||
/**
|
||||
* 砍价
|
||||
*/
|
||||
@@ -124,6 +113,9 @@ public class CartServiceImpl implements CartService {
|
||||
@Autowired
|
||||
private PromotionGoodsService promotionGoodsService;
|
||||
|
||||
@Autowired
|
||||
private WholesaleService wholesaleService;
|
||||
|
||||
@Override
|
||||
public void add(String skuId, Integer num, String cartType, Boolean cover) {
|
||||
AuthUser currentUser = Objects.requireNonNull(UserContext.getCurrentUser());
|
||||
@@ -132,7 +124,7 @@ public class CartServiceImpl implements CartService {
|
||||
}
|
||||
CartTypeEnum cartTypeEnum = getCartType(cartType);
|
||||
GoodsSku dataSku = checkGoods(skuId);
|
||||
Map<String, Object> promotionMap = this.getCurrentGoodsPromotion(dataSku, cartType);
|
||||
Map<String, Object> promotionMap = promotionGoodsService.getCurrentGoodsPromotion(dataSku, cartTypeEnum.name());
|
||||
|
||||
try {
|
||||
//购物车方式购买需要保存之前的选择,其他方式购买,则直接抹除掉之前的记录
|
||||
@@ -146,7 +138,7 @@ public class CartServiceImpl implements CartService {
|
||||
|
||||
|
||||
//购物车中已经存在,更新数量
|
||||
if (cartSkuVO != null && dataSku.getUpdateTime().equals(cartSkuVO.getGoodsSku().getUpdateTime())) {
|
||||
if (cartSkuVO != null && dataSku.getCreateTime().equals(cartSkuVO.getGoodsSku().getCreateTime())) {
|
||||
|
||||
//如果覆盖购物车中商品数量
|
||||
if (Boolean.TRUE.equals(cover)) {
|
||||
@@ -157,7 +149,7 @@ public class CartServiceImpl implements CartService {
|
||||
int newNum = oldNum + num;
|
||||
this.checkSetGoodsQuantity(cartSkuVO, skuId, newNum);
|
||||
}
|
||||
|
||||
cartSkuVO.setPromotionMap(promotionMap);
|
||||
//计算购物车小计
|
||||
cartSkuVO.setSubTotal(CurrencyUtil.mul(cartSkuVO.getPurchasePrice(), cartSkuVO.getNum()));
|
||||
} else {
|
||||
@@ -185,7 +177,6 @@ public class CartServiceImpl implements CartService {
|
||||
|
||||
//购物车中不存在此商品,则新建立一个
|
||||
CartSkuVO cartSkuVO = new CartSkuVO(dataSku, promotionMap);
|
||||
this.checkSetGoodsQuantity(cartSkuVO, skuId, num);
|
||||
cartSkuVO.setCartType(cartTypeEnum);
|
||||
//检测购物车数据
|
||||
checkCart(cartTypeEnum, cartSkuVO, skuId, num);
|
||||
@@ -194,10 +185,11 @@ public class CartServiceImpl implements CartService {
|
||||
cartSkuVOS.add(cartSkuVO);
|
||||
}
|
||||
|
||||
this.checkGoodsSaleModel(dataSku, tradeDTO.getSkuList());
|
||||
tradeDTO.setCartTypeEnum(cartTypeEnum);
|
||||
//如购物车发生更改,则重置优惠券
|
||||
tradeDTO.setStoreCoupons(null);
|
||||
tradeDTO.setPlatformCoupon(null);
|
||||
|
||||
remoteCoupon(tradeDTO);
|
||||
|
||||
this.resetTradeDTO(tradeDTO);
|
||||
} catch (ServiceException serviceException) {
|
||||
throw serviceException;
|
||||
@@ -241,39 +233,59 @@ public class CartServiceImpl implements CartService {
|
||||
@Override
|
||||
public void checked(String skuId, boolean checked) {
|
||||
TradeDTO tradeDTO = this.readDTO(CartTypeEnum.CART);
|
||||
|
||||
remoteCoupon(tradeDTO);
|
||||
|
||||
List<CartSkuVO> cartSkuVOS = tradeDTO.getSkuList();
|
||||
for (CartSkuVO cartSkuVO : cartSkuVOS) {
|
||||
if (cartSkuVO.getGoodsSku().getId().equals(skuId)) {
|
||||
cartSkuVO.setChecked(checked);
|
||||
}
|
||||
}
|
||||
cache.put(this.getOriginKey(CartTypeEnum.CART), tradeDTO);
|
||||
|
||||
this.resetTradeDTO(tradeDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkedStore(String storeId, boolean checked) {
|
||||
TradeDTO tradeDTO = this.readDTO(CartTypeEnum.CART);
|
||||
|
||||
remoteCoupon(tradeDTO);
|
||||
|
||||
List<CartSkuVO> cartSkuVOS = tradeDTO.getSkuList();
|
||||
for (CartSkuVO cartSkuVO : cartSkuVOS) {
|
||||
if (cartSkuVO.getStoreId().equals(storeId)) {
|
||||
cartSkuVO.setChecked(checked);
|
||||
}
|
||||
}
|
||||
cache.put(this.getOriginKey(CartTypeEnum.CART), tradeDTO);
|
||||
|
||||
resetTradeDTO(tradeDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkedAll(boolean checked) {
|
||||
TradeDTO tradeDTO = this.readDTO(CartTypeEnum.CART);
|
||||
|
||||
remoteCoupon(tradeDTO);
|
||||
|
||||
List<CartSkuVO> cartSkuVOS = tradeDTO.getSkuList();
|
||||
for (CartSkuVO cartSkuVO : cartSkuVOS) {
|
||||
cartSkuVO.setChecked(checked);
|
||||
}
|
||||
cache.put(this.getOriginKey(CartTypeEnum.CART), tradeDTO);
|
||||
resetTradeDTO(tradeDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当购物车商品发生变更时,取消已选择当优惠券
|
||||
*
|
||||
* @param tradeDTO
|
||||
*/
|
||||
private void remoteCoupon(TradeDTO tradeDTO) {
|
||||
tradeDTO.setPlatformCoupon(null);
|
||||
tradeDTO.setStoreCoupons(new HashMap<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(String[] skuIds) {
|
||||
TradeDTO tradeDTO = this.readDTO(CartTypeEnum.CART);
|
||||
List<CartSkuVO> cartSkuVOS = tradeDTO.getSkuList();
|
||||
@@ -286,7 +298,7 @@ public class CartServiceImpl implements CartService {
|
||||
}
|
||||
}
|
||||
cartSkuVOS.removeAll(deleteVos);
|
||||
cache.put(this.getOriginKey(CartTypeEnum.CART), tradeDTO);
|
||||
resetTradeDTO(tradeDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -308,17 +320,8 @@ public class CartServiceImpl implements CartService {
|
||||
tradeDTO.setStoreCoupons(null);
|
||||
//清除添加过的备注
|
||||
tradeDTO.setStoreRemark(null);
|
||||
cache.put(this.getOriginKey(tradeDTO.getCartTypeEnum()), tradeDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanChecked(CartTypeEnum way) {
|
||||
if (way.equals(CartTypeEnum.CART)) {
|
||||
TradeDTO tradeDTO = this.readDTO(CartTypeEnum.CART);
|
||||
this.cleanChecked(tradeDTO);
|
||||
} else {
|
||||
cache.remove(this.getOriginKey(way));
|
||||
}
|
||||
resetTradeDTO(tradeDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -415,7 +418,7 @@ public class CartServiceImpl implements CartService {
|
||||
cartSkuVO.setNum(num);
|
||||
}
|
||||
|
||||
if (cartSkuVO.getNum() > 99) {
|
||||
if (cartSkuVO.getGoodsSku() != null && !GoodsSalesModeEnum.WHOLESALE.name().equals(cartSkuVO.getGoodsSku().getSalesModel()) && cartSkuVO.getNum() > 99) {
|
||||
cartSkuVO.setNum(99);
|
||||
}
|
||||
}
|
||||
@@ -504,6 +507,12 @@ public class CartServiceImpl implements CartService {
|
||||
AuthUser currentUser = Objects.requireNonNull(UserContext.getCurrentUser());
|
||||
//获取购物车,然后重新写入优惠券
|
||||
CartTypeEnum cartTypeEnum = getCartType(way);
|
||||
|
||||
//积分商品不允许使用优惠券
|
||||
if (cartTypeEnum.equals(CartTypeEnum.POINTS)) {
|
||||
throw new ServiceException(ResultCode.SPECIAL_CANT_USE);
|
||||
}
|
||||
|
||||
TradeDTO tradeDTO = this.readDTO(cartTypeEnum);
|
||||
|
||||
MemberCouponSearchParams searchParams = new MemberCouponSearchParams();
|
||||
@@ -543,46 +552,10 @@ public class CartServiceImpl implements CartService {
|
||||
}
|
||||
//构建交易
|
||||
Trade trade = tradeBuilder.createTrade(tradeDTO);
|
||||
this.cleanChecked(tradeDTO);
|
||||
this.cleanChecked(this.readDTO(cartTypeEnum));
|
||||
return trade;
|
||||
}
|
||||
|
||||
private Map<String, Object> getCurrentGoodsPromotion(GoodsSku dataSku, String cartType) {
|
||||
Map<String, Object> promotionMap;
|
||||
EsGoodsIndex goodsIndex = goodsIndexService.findById(dataSku.getId());
|
||||
if (goodsIndex == null) {
|
||||
GoodsVO goodsVO = this.goodsService.getGoodsVO(dataSku.getGoodsId());
|
||||
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))) {
|
||||
|
||||
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 {
|
||||
promotionMap = null;
|
||||
}
|
||||
return promotionMap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取购物车类型
|
||||
@@ -636,6 +609,9 @@ public class CartServiceImpl implements CartService {
|
||||
cartPrice = CurrencyUtil.add(cartPrice, CurrencyUtil.mul(cartSkuVO.getGoodsSku().getPrice(), cartSkuVO.getNum()));
|
||||
skuPrice.put(cartSkuVO.getGoodsSku().getId(), CurrencyUtil.mul(cartSkuVO.getGoodsSku().getPrice(), cartSkuVO.getNum()));
|
||||
}
|
||||
} else {
|
||||
cartPrice = CurrencyUtil.add(cartPrice, CurrencyUtil.mul(cartSkuVO.getGoodsSku().getPrice(), cartSkuVO.getNum()));
|
||||
skuPrice.put(cartSkuVO.getGoodsSku().getId(), CurrencyUtil.mul(cartSkuVO.getGoodsSku().getPrice(), cartSkuVO.getNum()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -710,6 +686,24 @@ public class CartServiceImpl implements CartService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkGoodsSaleModel(GoodsSku dataSku, List<CartSkuVO> cartSkuVOS) {
|
||||
if (dataSku.getSalesModel().equals(GoodsSalesModeEnum.WHOLESALE.name())) {
|
||||
int numSum = 0;
|
||||
List<CartSkuVO> sameGoodsIdSkuList = cartSkuVOS.stream().filter(i -> i.getGoodsSku().getGoodsId().equals(dataSku.getGoodsId())).collect(Collectors.toList());
|
||||
if (CollUtil.isNotEmpty(sameGoodsIdSkuList)) {
|
||||
numSum += sameGoodsIdSkuList.stream().mapToInt(CartSkuVO::getNum).sum();
|
||||
}
|
||||
Wholesale match = wholesaleService.match(dataSku.getGoodsId(), numSum);
|
||||
if (match != null) {
|
||||
sameGoodsIdSkuList.forEach(i -> {
|
||||
i.setPurchasePrice(match.getPrice());
|
||||
i.setSubTotal(CurrencyUtil.mul(i.getPurchasePrice(), i.getNum()));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验拼团信息
|
||||
*
|
||||
|
||||
@@ -12,6 +12,7 @@ import cn.lili.modules.order.cart.entity.enums.DeliveryMethodEnum;
|
||||
import cn.lili.modules.order.cart.entity.vo.CartVO;
|
||||
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
|
||||
import cn.lili.modules.order.order.entity.enums.*;
|
||||
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
|
||||
import cn.lili.mybatis.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
@@ -78,6 +79,9 @@ public class Order extends BaseEntity {
|
||||
@ApiModelProperty(value = "第三方付款流水号")
|
||||
private String receivableNo;
|
||||
|
||||
/**
|
||||
* @see PaymentMethodEnum
|
||||
*/
|
||||
@ApiModelProperty(value = "支付方式")
|
||||
private String paymentMethod;
|
||||
|
||||
@@ -181,7 +185,7 @@ public class Order extends BaseEntity {
|
||||
@ApiModelProperty(value = "订单促销类型")
|
||||
private String orderPromotionType;
|
||||
|
||||
@ApiModelProperty(value = "价格详情")
|
||||
@ApiModelProperty(value = "价格价格详情")
|
||||
private String priceDetail;
|
||||
|
||||
@ApiModelProperty(value = "订单是否支持原路退回")
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
package cn.lili.modules.order.order.entity.dos;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.common.utils.BeanUtil;
|
||||
import cn.lili.common.utils.CurrencyUtil;
|
||||
import cn.lili.common.utils.SnowFlake;
|
||||
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
|
||||
import cn.lili.modules.order.order.entity.enums.FlowTypeEnum;
|
||||
import cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum;
|
||||
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
|
||||
import cn.lili.mybatis.BaseIdEntity;
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
@@ -9,6 +17,8 @@ import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
@@ -23,6 +33,8 @@ import java.util.Date;
|
||||
@Data
|
||||
@TableName("li_store_flow")
|
||||
@ApiModel(value = "商家订单流水")
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class StoreFlow extends BaseIdEntity {
|
||||
|
||||
private static final long serialVersionUID = -5998757398902747939L;
|
||||
@@ -92,10 +104,10 @@ public class StoreFlow extends BaseIdEntity {
|
||||
@ApiModelProperty(value = "平台优惠券 使用金额")
|
||||
private Double siteCouponPrice;
|
||||
|
||||
@ApiModelProperty(value = "站点优惠券佣金比例")
|
||||
@ApiModelProperty(value = "站点优惠券补贴比例")
|
||||
private Double siteCouponPoint;
|
||||
|
||||
@ApiModelProperty(value = "站点优惠券佣金")
|
||||
@ApiModelProperty(value = "站点优惠券补贴金额")
|
||||
private Double siteCouponCommission;
|
||||
|
||||
@ApiModelProperty(value = "单品分销返现支出")
|
||||
@@ -113,6 +125,9 @@ public class StoreFlow extends BaseIdEntity {
|
||||
@ApiModelProperty(value = "第三方交易流水号")
|
||||
private String transactionId;
|
||||
|
||||
/**
|
||||
* @see PaymentMethodEnum
|
||||
*/
|
||||
@ApiModelProperty(value = "支付方式名称")
|
||||
private String paymentName;
|
||||
|
||||
@@ -125,4 +140,62 @@ public class StoreFlow extends BaseIdEntity {
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@ApiModelProperty(value = "创建时间", hidden = true)
|
||||
private Date createTime;
|
||||
|
||||
|
||||
public StoreFlow(Order order, OrderItem item, FlowTypeEnum flowTypeEnum) {
|
||||
//获取订单促销类型,如果为促销订单则获取促销商品并获取结算价
|
||||
String promotionType = order.getOrderPromotionType();
|
||||
BeanUtil.copyProperties(item, this);
|
||||
|
||||
//去掉orderitem的时间。
|
||||
this.setCreateTime(null);
|
||||
//入账
|
||||
this.setId(SnowFlake.getIdStr());
|
||||
this.setFlowType(flowTypeEnum.name());
|
||||
this.setSn(SnowFlake.createStr("SF"));
|
||||
this.setOrderSn(item.getOrderSn());
|
||||
this.setOrderItemSn(item.getSn());
|
||||
this.setStoreId(order.getStoreId());
|
||||
this.setStoreName(order.getStoreName());
|
||||
this.setMemberId(order.getMemberId());
|
||||
this.setMemberName(order.getMemberName());
|
||||
this.setGoodsName(item.getGoodsName());
|
||||
this.setOrderPromotionType(item.getPromotionType());
|
||||
//格式化订单价格详情
|
||||
PriceDetailDTO priceDetailDTO = JSONUtil.toBean(item.getPriceDetail(), PriceDetailDTO.class);
|
||||
//站点优惠券比例=最大比例(100)-店铺承担比例
|
||||
this.setSiteCouponPoint(CurrencyUtil.sub(100, priceDetailDTO.getSiteCouponPoint()));
|
||||
//平台优惠券 使用金额
|
||||
this.setSiteCouponPrice(priceDetailDTO.getSiteCouponPrice());
|
||||
//站点优惠券佣金(站点优惠券承担金额=优惠券金额 * (站点承担比例/100))
|
||||
this.setSiteCouponCommission(CurrencyUtil.mul(this.getSiteCouponPrice(), CurrencyUtil.div(this.getSiteCouponPoint(), 100)));
|
||||
|
||||
/**
|
||||
* @TODO 计算平台佣金
|
||||
*/
|
||||
//店铺流水金额=goodsPrice(商品总金额(商品原价))+ freightPrice(配送费) - discountPrice(优惠金额) - couponPrice(优惠券金额) + updatePrice(订单修改金额)
|
||||
this.setFinalPrice(item.getPriceDetailDTO().getFlowPrice());
|
||||
//平台收取交易佣金=(flowPrice(流水金额) * platFormCommissionPoint(平台佣金比例))/100
|
||||
this.setCommissionPrice(item.getPriceDetailDTO().getPlatFormCommission());
|
||||
//单品分销返现支出
|
||||
this.setDistributionRebate(item.getPriceDetailDTO().getDistributionCommission());
|
||||
//最终结算金额=flowPrice(流水金额) - platFormCommission(平台收取交易佣金) - distributionCommission(单品分销返现支出)
|
||||
this.setBillPrice(item.getPriceDetailDTO().getBillPrice());
|
||||
//兼容为空,以及普通订单操作
|
||||
if (CharSequenceUtil.isNotEmpty(promotionType)) {
|
||||
//如果为砍价活动,填写砍价结算价
|
||||
if (promotionType.equals(OrderPromotionTypeEnum.KANJIA.name())) {
|
||||
this.setKanjiaSettlementPrice(item.getPriceDetailDTO().getSettlementPrice());
|
||||
}
|
||||
//如果为砍价活动,填写砍价结算价
|
||||
else if (promotionType.equals(OrderPromotionTypeEnum.POINTS.name())) {
|
||||
this.setPointSettlementPrice(item.getPriceDetailDTO().getSettlementPrice());
|
||||
}
|
||||
}
|
||||
//添加支付方式
|
||||
this.setPaymentName(order.getPaymentMethod());
|
||||
//添加第三方支付流水号
|
||||
this.setTransactionId(order.getReceivableNo());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,9 @@ public class Trade extends BaseEntity {
|
||||
@ApiModelProperty(value = "买家用户名")
|
||||
private String memberName;
|
||||
|
||||
/**
|
||||
* @see PayStatusEnum
|
||||
*/
|
||||
@ApiModelProperty(value = "支付方式")
|
||||
private String paymentMethod;
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ public class OrderSearchParams extends PageVO {
|
||||
|
||||
//关键字查询
|
||||
if (CharSequenceUtil.isNotEmpty(keywords)) {
|
||||
wrapper.like("o.sn", keywords).or().like("oi.goods_name", keywords);
|
||||
wrapper.and(keyWrapper -> keyWrapper.like("o.sn", keywords).or().like("oi.goods_name", keywords));
|
||||
}
|
||||
if (currentUser != null) {
|
||||
//按卖家查询
|
||||
|
||||
@@ -57,7 +57,8 @@ public class PriceDetailDTO implements Serializable {
|
||||
@ApiModelProperty(value = "平台收取交易佣金比例")
|
||||
private Double platFormCommissionPoint;
|
||||
|
||||
@ApiModelProperty(value = "平台收取交易佣金")
|
||||
|
||||
@ApiModelProperty(value = "平台收取交易佣金=(flowPrice(流水金额) * platFormCommissionPoint(平台佣金比例))/100")
|
||||
private Double platFormCommission;
|
||||
|
||||
//=========end distribution==========
|
||||
@@ -82,13 +83,15 @@ public class PriceDetailDTO implements Serializable {
|
||||
|
||||
//=========end update price==========
|
||||
|
||||
@ApiModelProperty(value = "流水金额(入账 出帐金额) = goodsPrice + freight - discountPrice - couponPrice + updatePrice")
|
||||
@ApiModelProperty(value = "流水金额(入账 出帐金额) = " +
|
||||
"goodsPrice(商品总金额(商品原价)) + freightPrice(配送费) - " +
|
||||
"discountPrice(优惠金额) - couponPrice(优惠券金额) + updatePrice(订单修改金额)")
|
||||
private Double flowPrice;
|
||||
|
||||
@ApiModelProperty(value = "结算价格 与 商家/供应商 结算价格(例如积分商品/砍价商品)")
|
||||
private Double settlementPrice;
|
||||
|
||||
@ApiModelProperty(value = "最终结算金额 = flowPrice - platFormCommission - distributionCommission")
|
||||
@ApiModelProperty(value = "最终结算金额 = flowPrice(流水金额) - platFormCommission(平台收取交易佣金) - distributionCommission(单品分销返现支出)")
|
||||
private Double billPrice;
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@ import cn.lili.modules.order.order.entity.enums.OrderComplaintStatusEnum;
|
||||
import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 子订单VO
|
||||
@@ -13,6 +14,7 @@ import lombok.Data;
|
||||
* @since 2020-08-17 20:28
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class OrderItemVO {
|
||||
|
||||
@ApiModelProperty(value = "编号")
|
||||
@@ -55,17 +57,39 @@ public class OrderItemVO {
|
||||
private String commentStatus;
|
||||
|
||||
|
||||
public OrderItemVO(String sn, String goodsId, String skuId, String num, String image, String name, String afterSaleStatus, String complainStatus, String commentStatus, Double goodsPrice) {
|
||||
public void setSn(String sn) {
|
||||
this.sn = sn;
|
||||
this.goodsId = goodsId;
|
||||
}
|
||||
|
||||
public void setSkuId(String skuId) {
|
||||
this.skuId = skuId;
|
||||
}
|
||||
|
||||
public void setNum(String num) {
|
||||
this.num = num;
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
this.afterSaleStatus = afterSaleStatus;
|
||||
this.complainStatus = complainStatus;
|
||||
this.commentStatus = commentStatus;
|
||||
}
|
||||
|
||||
public void setGoodsPrice(Double goodsPrice) {
|
||||
this.goodsPrice = goodsPrice;
|
||||
}
|
||||
|
||||
public void setAfterSaleStatus(String afterSaleStatus) {
|
||||
this.afterSaleStatus = afterSaleStatus;
|
||||
}
|
||||
|
||||
public void setComplainStatus(String complainStatus) {
|
||||
this.complainStatus = complainStatus;
|
||||
}
|
||||
|
||||
public void setCommentStatus(String commentStatus) {
|
||||
this.commentStatus = commentStatus;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package cn.lili.modules.order.order.entity.vo;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.lili.common.enums.ClientTypeEnum;
|
||||
import cn.lili.common.utils.StringUtils;
|
||||
import cn.lili.modules.order.order.entity.enums.*;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
@@ -135,28 +134,54 @@ public class OrderSimpleVO {
|
||||
private String deliverStatus;
|
||||
|
||||
public List<OrderItemVO> getOrderItems() {
|
||||
if (StringUtils.isEmpty(groupGoodsId)) {
|
||||
if (CharSequenceUtil.isEmpty(groupGoodsId)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<OrderItemVO> orderItemVOS = new ArrayList<>();
|
||||
String[] orderItemsSn = groupOrderItemsSn.split(",");
|
||||
|
||||
|
||||
String[] goodsId = groupGoodsId.split(",");
|
||||
String[] skuId = groupSkuId.split(",");
|
||||
String[] num = groupNum.split(",");
|
||||
String[] image = groupImages.split(",");
|
||||
String[] name = groupName.split(",");
|
||||
String[] afterSaleStatus = groupAfterSaleStatus.split(",");
|
||||
String[] complainStatus = groupComplainStatus.split(",");
|
||||
String[] commentStatus = groupCommentStatus.split(",");
|
||||
String[] goodsPrice = groupGoodsPrice.split(",");
|
||||
|
||||
for (int i = 0; i < goodsId.length; i++) {
|
||||
orderItemVOS.add(new OrderItemVO(orderItemsSn[i], goodsId[i], skuId[i], num[i], image[i], name[i], afterSaleStatus[i], complainStatus[i], commentStatus[i], Double.parseDouble(goodsPrice[i])));
|
||||
orderItemVOS.add(this.getOrderItemVO(i));
|
||||
}
|
||||
return orderItemVOS;
|
||||
|
||||
}
|
||||
|
||||
private OrderItemVO getOrderItemVO(int i) {
|
||||
OrderItemVO orderItemVO = new OrderItemVO();
|
||||
orderItemVO.setGoodsId(groupGoodsId.split(",")[i]);
|
||||
if (CharSequenceUtil.isNotEmpty(groupOrderItemsSn)) {
|
||||
orderItemVO.setSn(groupOrderItemsSn.split(",")[i]);
|
||||
}
|
||||
if (CharSequenceUtil.isNotEmpty(groupSkuId)) {
|
||||
orderItemVO.setSkuId(groupSkuId.split(",")[i]);
|
||||
}
|
||||
if (CharSequenceUtil.isNotEmpty(groupName)) {
|
||||
orderItemVO.setName(groupName.split(",")[i]);
|
||||
}
|
||||
if (CharSequenceUtil.isNotEmpty(groupNum) && groupNum.split(",").length == groupGoodsId.split(",").length) {
|
||||
orderItemVO.setNum(groupNum.split(",")[i]);
|
||||
}
|
||||
if (CharSequenceUtil.isNotEmpty(groupImages) && groupImages.split(",").length == groupGoodsId.split(",").length) {
|
||||
orderItemVO.setImage(groupImages.split(",")[i]);
|
||||
}
|
||||
if (CharSequenceUtil.isNotEmpty(groupAfterSaleStatus) && groupAfterSaleStatus.split(",").length == groupGoodsId.split(",").length) {
|
||||
orderItemVO.setAfterSaleStatus(groupAfterSaleStatus.split(",")[i]);
|
||||
}
|
||||
if (CharSequenceUtil.isNotEmpty(groupComplainStatus) && groupComplainStatus.split(",").length == groupGoodsId.split(",").length) {
|
||||
orderItemVO.setComplainStatus(groupComplainStatus.split(",")[i]);
|
||||
}
|
||||
if (CharSequenceUtil.isNotEmpty(groupCommentStatus) && groupCommentStatus.split(",").length == groupGoodsId.split(",").length) {
|
||||
orderItemVO.setCommentStatus(groupCommentStatus.split(",")[i]);
|
||||
}
|
||||
if (CharSequenceUtil.isNotEmpty(groupGoodsPrice) && groupGoodsPrice.split(",").length == groupGoodsId.split(",").length) {
|
||||
orderItemVO.setGoodsPrice(Double.parseDouble(groupGoodsPrice.split(",")[i]));
|
||||
}
|
||||
return orderItemVO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化自身状态
|
||||
*/
|
||||
|
||||
@@ -10,16 +10,14 @@ import cn.hutool.poi.excel.ExcelUtil;
|
||||
import cn.hutool.poi.excel.ExcelWriter;
|
||||
import cn.lili.common.enums.PromotionTypeEnum;
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.event.TransactionCommitSendMQEvent;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.fulu.core.utils.Test;
|
||||
import cn.lili.common.properties.RocketmqCustomProperties;
|
||||
import cn.lili.common.security.OperationalJudgment;
|
||||
import cn.lili.common.security.context.UserContext;
|
||||
import cn.lili.common.security.enums.UserEnums;
|
||||
import cn.lili.common.utils.SnowFlake;
|
||||
import cn.lili.modules.goods.entity.dos.Goods;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsCompleteMessage;
|
||||
import cn.lili.modules.goods.service.GoodsService;
|
||||
import cn.lili.modules.member.entity.dto.MemberAddressDTO;
|
||||
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
|
||||
import cn.lili.modules.order.order.aop.OrderLogPoint;
|
||||
@@ -41,9 +39,6 @@ import cn.lili.modules.order.trade.service.OrderLogService;
|
||||
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
|
||||
import cn.lili.modules.promotion.entity.dos.Pintuan;
|
||||
import cn.lili.modules.promotion.service.PintuanService;
|
||||
import cn.lili.modules.store.entity.dos.StoreDetail;
|
||||
import cn.lili.modules.store.entity.dto.FuLuConfigureDTO;
|
||||
import cn.lili.modules.store.service.StoreDetailService;
|
||||
import cn.lili.modules.system.aspect.annotation.SystemLogPoint;
|
||||
import cn.lili.modules.system.entity.dos.Logistics;
|
||||
import cn.lili.modules.system.entity.vo.Traces;
|
||||
@@ -58,7 +53,6 @@ import cn.lili.trigger.message.PintuanOrderMessage;
|
||||
import cn.lili.trigger.model.TimeExecuteConstant;
|
||||
import cn.lili.trigger.model.TimeTriggerMsg;
|
||||
import cn.lili.trigger.util.DelayQueueTools;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
@@ -66,9 +60,11 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
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;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@@ -88,6 +84,7 @@ import java.util.stream.Collectors;
|
||||
* @since 2020/11/17 7:38 下午
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
|
||||
|
||||
private static final String ORDER_SN_COLUMN = "order_sn";
|
||||
@@ -146,17 +143,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
@Autowired
|
||||
private TradeService tradeService;
|
||||
|
||||
/**
|
||||
* 商品
|
||||
*/
|
||||
@Autowired
|
||||
private GoodsService goodsService;
|
||||
|
||||
/**
|
||||
* 商品
|
||||
*/
|
||||
@Autowired
|
||||
private StoreDetailService storeDetailService;
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@@ -313,6 +302,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
order.setCancelReason(reason);
|
||||
//修改订单
|
||||
this.updateById(order);
|
||||
//生成店铺退款流水
|
||||
this.generatorStoreRefundFlow(order);
|
||||
orderStatusMessage(order);
|
||||
return order;
|
||||
} else {
|
||||
@@ -329,6 +320,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
order.setOrderStatus(OrderStatusEnum.CANCELLED.name());
|
||||
order.setCancelReason(reason);
|
||||
this.updateById(order);
|
||||
//生成店铺退款流水
|
||||
this.generatorStoreRefundFlow(order);
|
||||
orderStatusMessage(order);
|
||||
}
|
||||
|
||||
@@ -350,6 +343,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
Order order = this.getBySn(orderSn);
|
||||
//如果订单已支付,就不能再次进行支付
|
||||
if (order.getPayStatus().equals(PayStatusEnum.PAID.name())) {
|
||||
log.error("订单[ {} ]检测到重复付款,请处理", orderSn);
|
||||
throw new ServiceException(ResultCode.PAY_DOUBLE_ERROR);
|
||||
}
|
||||
|
||||
@@ -362,7 +356,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
order.setCanReturn(!PaymentMethodEnum.BANK_TRANSFER.name().equals(order.getPaymentMethod()));
|
||||
this.updateById(order);
|
||||
|
||||
//记录订单流水
|
||||
//记录店铺订单支付流水
|
||||
storeFlowService.payOrder(orderSn);
|
||||
|
||||
//发送订单已付款消息
|
||||
@@ -458,11 +452,13 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
//获取订单信息
|
||||
Order order = this.getBySn(orderSn);
|
||||
//获取踪迹信息
|
||||
return logisticsService.getLogistic(order.getLogisticsCode(), order.getLogisticsNo());
|
||||
String str = order.getConsigneeMobile();
|
||||
return logisticsService.getLogistic(order.getLogisticsCode(), order.getLogisticsNo(), str.substring(str.length() - 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
@OrderLogPoint(description = "'订单['+#orderSn+']核销,核销码['+#verificationCode+']'", orderSn = "#orderSn")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Order take(String orderSn, String verificationCode) {
|
||||
|
||||
//获取订单信息
|
||||
@@ -507,7 +503,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
* @param order 订单
|
||||
* @param orderSn 订单编号
|
||||
*/
|
||||
private void complete(Order order, String orderSn) {//修改订单状态为完成
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void complete(Order order, String orderSn) {//修改订单状态为完成
|
||||
this.updateStatus(orderSn, OrderStatusEnum.COMPLETED);
|
||||
|
||||
//修改订单货物可以进行评价
|
||||
@@ -546,10 +543,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void sendUpdateStatusMessage(OrderMessage orderMessage) {
|
||||
String destination = rocketmqCustomProperties.getOrderTopic() + ":" + OrderTagsEnum.STATUS_CHANGE.name();
|
||||
//发送订单变更mq消息
|
||||
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(orderMessage), RocketmqSendCallbackBuilder.commonCallback());
|
||||
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("发送订单变更mq消息", rocketmqCustomProperties.getOrderTopic(), OrderTagsEnum.STATUS_CHANGE.name(), JSONUtil.toJsonStr(orderMessage)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -633,6 +629,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchDeliver(MultipartFile files) {
|
||||
|
||||
InputStream inputStream;
|
||||
@@ -721,6 +718,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean checkFictitiousOrder(String pintuanId, Integer requiredNum, Boolean fictitious) {
|
||||
Map<String, List<Order>> collect = this.queryListByPromotion(pintuanId)
|
||||
.stream().collect(Collectors.groupingBy(Order::getParentOrderSn));
|
||||
@@ -788,15 +786,35 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
/**
|
||||
* 订单状态变更消息
|
||||
*
|
||||
* @param order
|
||||
* @param order 订单信息
|
||||
*/
|
||||
private void orderStatusMessage(Order order) {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void orderStatusMessage(Order order) {
|
||||
OrderMessage orderMessage = new OrderMessage();
|
||||
orderMessage.setOrderSn(order.getSn());
|
||||
orderMessage.setNewStatus(OrderStatusEnum.valueOf(order.getOrderStatus()));
|
||||
this.sendUpdateStatusMessage(orderMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成店铺退款流水
|
||||
*
|
||||
* @param order 订单信息
|
||||
*/
|
||||
private void generatorStoreRefundFlow(Order order) {
|
||||
// 判断订单是否是付款
|
||||
if (!PayStatusEnum.PAID.name().equals((order.getPayStatus()))) {
|
||||
return;
|
||||
}
|
||||
List<OrderItem> items = orderItemService.getByOrderSn(order.getSn());
|
||||
List<StoreFlow> storeFlows = new ArrayList<>();
|
||||
for (OrderItem item : items) {
|
||||
StoreFlow storeFlow = new StoreFlow(order, item, FlowTypeEnum.REFUND);
|
||||
storeFlows.add(storeFlow);
|
||||
}
|
||||
storeFlowService.saveBatch(storeFlows);
|
||||
}
|
||||
|
||||
/**
|
||||
* 此方法只提供内部调用,调用前应该做好权限处理
|
||||
* 修改订单状态
|
||||
@@ -822,11 +840,10 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
List<Order> list = this.getPintuanOrder(pintuanId, parentOrderSn);
|
||||
int count = list.size();
|
||||
if (count == 1) {
|
||||
//如果为开团订单,则发布一个一小时的延时任务,时间到达后,如果未成团则自动结束(未开启虚拟成团的情况下)
|
||||
//如果为开团订单,则发布一个24小时的延时任务,时间到达后,如果未成团则自动结束(未开启虚拟成团的情况下)
|
||||
PintuanOrderMessage pintuanOrderMessage = new PintuanOrderMessage();
|
||||
//开团结束时间
|
||||
// long startTime = DateUtil.offsetHour(new Date(), 1).getTime();
|
||||
long startTime = DateUtil.offsetMinute(new Date(), 2).getTime();
|
||||
long startTime = DateUtil.offsetHour(new Date(), 24).getTime();
|
||||
pintuanOrderMessage.setOrderSn(parentOrderSn);
|
||||
pintuanOrderMessage.setPintuanId(pintuanId);
|
||||
TimeTriggerMsg timeTriggerMsg = new TimeTriggerMsg(TimeExecuteConstant.PROMOTION_EXECUTOR,
|
||||
@@ -918,7 +935,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
*
|
||||
* @param orderSn 订单编号
|
||||
*/
|
||||
private void normalOrderConfirm(String orderSn) {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void normalOrderConfirm(String orderSn) {
|
||||
//修改订单
|
||||
this.update(new LambdaUpdateWrapper<Order>()
|
||||
.eq(Order::getSn, orderSn)
|
||||
@@ -937,7 +955,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
*
|
||||
* @param orderSn 订单编号
|
||||
*/
|
||||
private void virtualOrderConfirm(String orderSn) {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void virtualOrderConfirm(String orderSn) {
|
||||
//修改订单
|
||||
this.update(new LambdaUpdateWrapper<Order>()
|
||||
.eq(Order::getSn, orderSn)
|
||||
@@ -960,71 +979,16 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
throw new ServiceException(ResultCode.ORDER_NOT_EXIST);
|
||||
}
|
||||
//判断是否为虚拟订单
|
||||
else if (!order.getOrderType().equals(OrderTypeEnum.VIRTUAL.name())) {
|
||||
if (!order.getOrderType().equals(OrderTypeEnum.VIRTUAL.name())) {
|
||||
throw new ServiceException(ResultCode.ORDER_TAKE_ERROR);
|
||||
}
|
||||
//判断虚拟订单状态
|
||||
else if (!order.getOrderStatus().equals(OrderStatusEnum.TAKE.name())) {
|
||||
if (!order.getOrderStatus().equals(OrderStatusEnum.TAKE.name())) {
|
||||
throw new ServiceException(ResultCode.ORDER_TAKE_ERROR);
|
||||
}
|
||||
//判断验证码是否正确
|
||||
else if (!verificationCode.equals(order.getVerificationCode())) {
|
||||
if (!verificationCode.equals(order.getVerificationCode())) {
|
||||
throw new ServiceException(ResultCode.ORDER_TAKE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取订单
|
||||
*
|
||||
* @param receivableNo 微信支付单号
|
||||
* @return 订单详情
|
||||
*/
|
||||
@Override
|
||||
public Order getOrderByReceivableNo(String receivableNo) {
|
||||
return this.getOne(new LambdaQueryWrapper<Order>().eq(Order::getReceivableNo, receivableNo));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验证福禄订单进行处理
|
||||
*
|
||||
* @param tradeNo 第三方流水
|
||||
*/
|
||||
@Override
|
||||
public void fuluOrder(String tradeNo) {
|
||||
Order order = this.getOrderByReceivableNo(tradeNo);
|
||||
if (order != null) {
|
||||
List<StoreFlow> storeFlows = storeFlowService.list(new LambdaQueryWrapper<StoreFlow>().eq(StoreFlow::getOrderSn, order.getSn()));
|
||||
if (storeFlows.size() > 0) {
|
||||
Goods goods = goodsService.getById(storeFlows.get(0).getGoodsId());
|
||||
if (goods != null) {
|
||||
FuLuConfigureDTO fuLuConfigureDTO = new FuLuConfigureDTO();
|
||||
StoreDetail storeDetail = storeDetailService.getOne(
|
||||
new LambdaQueryWrapper<StoreDetail>()
|
||||
.eq(StoreDetail::getStoreId, storeFlows.get(0).getStoreId())
|
||||
);
|
||||
|
||||
fuLuConfigureDTO.setAppSecretKey(storeDetail.getAppSecretKey());
|
||||
fuLuConfigureDTO.setMerchantNumber(storeDetail.getMerchantNumber());
|
||||
fuLuConfigureDTO.setAppMerchantKey(storeDetail.getAppMerchantKey());
|
||||
try {
|
||||
if (goods.getBrandId().equals("1496301301183672321")) {
|
||||
Map map1 = (Map) JSON.parse(Test.productInfoGetTest(fuLuConfigureDTO, goods.getSn()).get("result").toString());
|
||||
|
||||
if (map1.get("product_type").toString().equals("直充")) {
|
||||
Test.directOrderAddTest(fuLuConfigureDTO, Integer.valueOf(goods.getSn()), order.getGoodsNum(), order.getQrCode(), order.getSn());
|
||||
} else if (map1.get("product_type").toString().equals("卡密")) {
|
||||
Test.cardOrderAddTest(fuLuConfigureDTO, Integer.valueOf(goods.getSn()), order.getGoodsNum(), order.getSn());
|
||||
} else {
|
||||
//不是直充也不是卡密需要修改代码
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package cn.lili.modules.order.order.serviceimpl;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.lili.common.utils.BeanUtil;
|
||||
import cn.lili.common.utils.CurrencyUtil;
|
||||
import cn.lili.common.utils.SnowFlake;
|
||||
import cn.lili.common.vo.PageVO;
|
||||
@@ -11,8 +10,6 @@ import cn.lili.modules.order.order.entity.dos.OrderItem;
|
||||
import cn.lili.modules.order.order.entity.dos.StoreFlow;
|
||||
import cn.lili.modules.order.order.entity.dto.StoreFlowQueryDTO;
|
||||
import cn.lili.modules.order.order.entity.enums.FlowTypeEnum;
|
||||
import cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum;
|
||||
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
|
||||
import cn.lili.modules.order.order.mapper.StoreFlowMapper;
|
||||
import cn.lili.modules.order.order.service.OrderItemService;
|
||||
import cn.lili.modules.order.order.service.OrderService;
|
||||
@@ -64,6 +61,11 @@ public class StoreFlowServiceImpl extends ServiceImpl<StoreFlowMapper, StoreFlow
|
||||
@Autowired
|
||||
private BillService billService;
|
||||
|
||||
/**
|
||||
* 店铺订单支付流水
|
||||
*
|
||||
* @param orderSn 订单编号
|
||||
*/
|
||||
@Override
|
||||
public void payOrder(String orderSn) {
|
||||
//根据订单编号获取子订单列表
|
||||
@@ -71,61 +73,20 @@ public class StoreFlowServiceImpl extends ServiceImpl<StoreFlowMapper, StoreFlow
|
||||
//根据订单编号获取订单数据
|
||||
Order order = orderService.getBySn(orderSn);
|
||||
|
||||
//如果查询到多条支付记录,打印日志
|
||||
if (order.getPayStatus().equals(PayStatusEnum.PAID.name())) {
|
||||
log.error("订单[{}]检测到重复付款,请处理", orderSn);
|
||||
}
|
||||
|
||||
//获取订单促销类型,如果为促销订单则获取促销商品并获取结算价
|
||||
String orderPromotionType = order.getOrderPromotionType();
|
||||
//循环子订单记录流水
|
||||
for (OrderItem item : orderItems) {
|
||||
StoreFlow storeFlow = new StoreFlow();
|
||||
BeanUtil.copyProperties(item, storeFlow);
|
||||
|
||||
//入账
|
||||
storeFlow.setId(SnowFlake.getIdStr());
|
||||
storeFlow.setFlowType(FlowTypeEnum.PAY.name());
|
||||
storeFlow.setSn(SnowFlake.createStr("SF"));
|
||||
storeFlow.setOrderSn(item.getOrderSn());
|
||||
storeFlow.setOrderItemSn(item.getSn());
|
||||
storeFlow.setStoreId(order.getStoreId());
|
||||
storeFlow.setStoreName(order.getStoreName());
|
||||
storeFlow.setMemberId(order.getMemberId());
|
||||
storeFlow.setMemberName(order.getMemberName());
|
||||
storeFlow.setGoodsName(item.getGoodsName());
|
||||
|
||||
storeFlow.setOrderPromotionType(item.getPromotionType());
|
||||
|
||||
//计算平台佣金
|
||||
storeFlow.setFinalPrice(item.getPriceDetailDTO().getFlowPrice());
|
||||
storeFlow.setCommissionPrice(item.getPriceDetailDTO().getPlatFormCommission());
|
||||
storeFlow.setDistributionRebate(item.getPriceDetailDTO().getDistributionCommission());
|
||||
storeFlow.setBillPrice(item.getPriceDetailDTO().getBillPrice());
|
||||
//兼容为空,以及普通订单操作
|
||||
if (CharSequenceUtil.isNotEmpty(orderPromotionType)) {
|
||||
if (orderPromotionType.equals(OrderPromotionTypeEnum.NORMAL.name())) {
|
||||
//普通订单操作
|
||||
}
|
||||
//如果为砍价活动,填写砍价结算价
|
||||
else if (orderPromotionType.equals(OrderPromotionTypeEnum.KANJIA.name())) {
|
||||
storeFlow.setKanjiaSettlementPrice(item.getPriceDetailDTO().getSettlementPrice());
|
||||
}
|
||||
//如果为砍价活动,填写砍价结算价
|
||||
else if (orderPromotionType.equals(OrderPromotionTypeEnum.POINTS.name())) {
|
||||
storeFlow.setPointSettlementPrice(item.getPriceDetailDTO().getSettlementPrice());
|
||||
}
|
||||
}
|
||||
//添加支付方式
|
||||
storeFlow.setPaymentName(order.getPaymentMethod());
|
||||
//添加第三方支付流水号
|
||||
storeFlow.setTransactionId(order.getReceivableNo());
|
||||
|
||||
StoreFlow storeFlow = new StoreFlow(order, item, FlowTypeEnum.PAY);
|
||||
//添加付款交易流水
|
||||
this.save(storeFlow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 店铺订单退款流水
|
||||
*
|
||||
* @param afterSale 售后单
|
||||
*/
|
||||
@Override
|
||||
public void refundOrder(AfterSale afterSale) {
|
||||
StoreFlow storeFlow = new StoreFlow();
|
||||
@@ -149,19 +110,29 @@ public class StoreFlowServiceImpl extends ServiceImpl<StoreFlowMapper, StoreFlow
|
||||
//获取付款信息
|
||||
StoreFlow payStoreFlow = this.getOne(new LambdaUpdateWrapper<StoreFlow>().eq(StoreFlow::getOrderItemSn, afterSale.getOrderItemSn())
|
||||
.eq(StoreFlow::getFlowType, FlowTypeEnum.PAY));
|
||||
//申请商品退款数量
|
||||
storeFlow.setNum(afterSale.getNum());
|
||||
//分类ID
|
||||
storeFlow.setCategoryId(payStoreFlow.getCategoryId());
|
||||
//佣金
|
||||
//佣金 = (佣金/订单商品数量)* 售后商品数量
|
||||
storeFlow.setCommissionPrice(CurrencyUtil.mul(CurrencyUtil.div(payStoreFlow.getCommissionPrice(), payStoreFlow.getNum()), afterSale.getNum()));
|
||||
//分销佣金
|
||||
//分销佣金 =(分销佣金/订单商品数量)* 售后商品数量
|
||||
storeFlow.setDistributionRebate(CurrencyUtil.mul(CurrencyUtil.div(payStoreFlow.getDistributionRebate(), payStoreFlow.getNum()), afterSale.getNum()));
|
||||
//流水金额
|
||||
storeFlow.setFinalPrice(afterSale.getActualRefundPrice());
|
||||
//最终结算金额
|
||||
storeFlow.setBillPrice(CurrencyUtil.add(storeFlow.getFinalPrice(), storeFlow.getDistributionRebate(), storeFlow.getCommissionPrice()));
|
||||
//获取第三方支付流水号
|
||||
//流水金额 = 支付最终结算金额
|
||||
storeFlow.setFinalPrice(payStoreFlow.getBillPrice());
|
||||
//最终结算金额 =实际退款金额
|
||||
storeFlow.setBillPrice(afterSale.getActualRefundPrice());
|
||||
//站点优惠券补贴返还金额=(站点优惠券补贴金额/购买商品数量)*退款商品数量
|
||||
storeFlow.setSiteCouponCommission(CurrencyUtil.mul(CurrencyUtil.div(payStoreFlow.getSiteCouponCommission(), payStoreFlow.getNum()), afterSale.getNum()));
|
||||
//平台优惠券 使用金额
|
||||
storeFlow.setSiteCouponPrice(payStoreFlow.getSiteCouponPrice());
|
||||
//站点优惠券佣金比例
|
||||
storeFlow.setSiteCouponPoint(payStoreFlow.getSiteCouponPoint());
|
||||
//退款日志
|
||||
RefundLog refundLog = refundLogService.queryByAfterSaleSn(afterSale.getSn());
|
||||
//第三方流水单号
|
||||
storeFlow.setTransactionId(refundLog.getReceivableNo());
|
||||
//支付方式
|
||||
storeFlow.setPaymentName(refundLog.getPaymentName());
|
||||
this.save(storeFlow);
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -53,7 +53,7 @@ public interface ArticleService extends IService<Article> {
|
||||
Article updateArticle(Article article);
|
||||
|
||||
/**
|
||||
* 删除文章
|
||||
* 删除文章--id
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
@@ -87,4 +87,12 @@ public interface ArticleService extends IService<Article> {
|
||||
*/
|
||||
@CacheEvict(key = "#id")
|
||||
Boolean updateArticleStatus(String id, boolean status);
|
||||
|
||||
/**
|
||||
* 修改文章--文章类型修改
|
||||
* @param article
|
||||
* @return
|
||||
*/
|
||||
@CacheEvict(key = "#article.type")
|
||||
Article updateArticleType(Article article);
|
||||
}
|
||||
@@ -91,4 +91,12 @@ public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> impl
|
||||
article.setOpenStatus(status);
|
||||
return this.updateById(article);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Article updateArticleType(Article article) {
|
||||
Article oldArticle = this.getById(article.getId());
|
||||
BeanUtil.copyProperties(article, oldArticle);
|
||||
this.updateById(oldArticle);
|
||||
return oldArticle;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.lili.modules.page.serviceimpl;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.lili.common.enums.ClientTypeEnum;
|
||||
@@ -82,12 +83,11 @@ public class PageDataServiceImpl extends ServiceImpl<PageDataMapper, PageData> i
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public PageData updatePageData(PageData pageData) {
|
||||
|
||||
//如果页面为发布,则关闭其他页面,开启此页面
|
||||
if (pageData.getPageShow() != null && pageData.getPageShow().equals(SwitchEnum.OPEN.name())) {
|
||||
LambdaUpdateWrapper<PageData> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
|
||||
lambdaUpdateWrapper.eq(PageData::getPageType, pageData.getPageType());
|
||||
lambdaUpdateWrapper.eq(PageData::getPageClientType, pageData.getPageClientType());
|
||||
lambdaUpdateWrapper.eq(CharSequenceUtil.isNotEmpty(pageData.getPageType()), PageData::getPageType, pageData.getPageType());
|
||||
lambdaUpdateWrapper.eq(CharSequenceUtil.isNotEmpty(pageData.getPageClientType()), PageData::getPageClientType, pageData.getPageClientType());
|
||||
lambdaUpdateWrapper.set(PageData::getPageShow, SwitchEnum.CLOSE.name());
|
||||
lambdaUpdateWrapper.set(StrUtil.isNotEmpty(pageData.getNum()), PageData::getNum, SwitchEnum.CLOSE.name());
|
||||
this.update(lambdaUpdateWrapper);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.lili.modules.payment.entity;
|
||||
|
||||
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
|
||||
import cn.lili.mybatis.BaseIdEntity;
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
@@ -48,6 +49,9 @@ public class RefundLog extends BaseIdEntity {
|
||||
@ApiModelProperty(value = "是否已退款")
|
||||
private Boolean isRefund;
|
||||
|
||||
/**
|
||||
* @see PaymentMethodEnum
|
||||
*/
|
||||
@ApiModelProperty(value = "退款方式")
|
||||
private String paymentName;
|
||||
|
||||
|
||||
@@ -83,17 +83,6 @@ public interface Payment {
|
||||
throw new ServiceException(ResultCode.PAY_ERROR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取消支付订单
|
||||
*
|
||||
* @param refundLog 支付参数
|
||||
*/
|
||||
default void cancel(RefundLog refundLog) {
|
||||
throw new ServiceException(ResultCode.PAY_ERROR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 回调
|
||||
*
|
||||
@@ -131,6 +120,7 @@ public interface Payment {
|
||||
default String callbackUrl(String api, PaymentMethodEnum paymentMethodEnum) {
|
||||
return api + "/buyer/payment/cashier/callback/" + paymentMethodEnum.name();
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付异步通知地址
|
||||
*
|
||||
|
||||
@@ -75,7 +75,6 @@ public class RefundSupport {
|
||||
*
|
||||
* @return void
|
||||
* @Author ftyy
|
||||
* @Description //TODO
|
||||
* @Date 17:33 2021/11/18
|
||||
* @Param [afterSale]
|
||||
**/
|
||||
@@ -89,31 +88,6 @@ public class RefundSupport {
|
||||
orderItemService.updateById(orderItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单取消
|
||||
*
|
||||
* @param afterSale
|
||||
*/
|
||||
public void cancel(AfterSale afterSale) {
|
||||
|
||||
Order order = orderService.getBySn(afterSale.getOrderSn());
|
||||
RefundLog refundLog = RefundLog.builder()
|
||||
.isRefund(false)
|
||||
.totalAmount(afterSale.getActualRefundPrice())
|
||||
.payPrice(afterSale.getActualRefundPrice())
|
||||
.memberId(afterSale.getMemberId())
|
||||
.paymentName(order.getPaymentMethod())
|
||||
.afterSaleNo(afterSale.getSn())
|
||||
.paymentReceivableNo(order.getReceivableNo())
|
||||
.outOrderNo("AF" + SnowFlake.getIdStr())
|
||||
.orderSn(afterSale.getOrderSn())
|
||||
.refundReason(afterSale.getReason())
|
||||
.build();
|
||||
PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.paymentNameOf(order.getPaymentMethod());
|
||||
Payment payment = (Payment) SpringContextUtil.getBean(paymentMethodEnum.getPlugin());
|
||||
payment.refund(refundLog);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 退款通知
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package cn.lili.modules.payment.kit.core.http;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.net.SSLContextBuilder;
|
||||
import cn.hutool.core.net.SSLProtocols;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.http.ssl.SSLSocketFactoryBuilder;
|
||||
import cn.lili.modules.payment.kit.core.PaymentHttpResponse;
|
||||
|
||||
import javax.net.ssl.KeyManager;
|
||||
@@ -235,12 +236,12 @@ public abstract class AbstractHttpDelegate {
|
||||
try {
|
||||
File file = FileUtil.newFile(filePath);
|
||||
return HttpRequest.post(url)
|
||||
.setSSLSocketFactory(SSLSocketFactoryBuilder
|
||||
.setSSLSocketFactory(SSLContextBuilder
|
||||
.create()
|
||||
.setProtocol(protocol)
|
||||
.setKeyManagers(getKeyManager(certPass, certPath, null))
|
||||
.setSecureRandom(new SecureRandom())
|
||||
.build()
|
||||
.build().getSocketFactory()
|
||||
)
|
||||
.header("Content-Type", "multipart/form-data;boundary=\"boundary\"")
|
||||
.form("file", file)
|
||||
@@ -263,7 +264,7 @@ public abstract class AbstractHttpDelegate {
|
||||
* @return {@link String} 请求返回的结果
|
||||
*/
|
||||
public String upload(String url, String data, String certPath, String certPass, String filePath) {
|
||||
return upload(url, data, certPath, certPass, filePath, SSLSocketFactoryBuilder.TLSv1);
|
||||
return upload(url, data, certPath, certPass, filePath, SSLProtocols.TLSv1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,12 +280,12 @@ public abstract class AbstractHttpDelegate {
|
||||
public String post(String url, String data, String certPath, String certPass, String protocol) {
|
||||
try {
|
||||
return HttpRequest.post(url)
|
||||
.setSSLSocketFactory(SSLSocketFactoryBuilder
|
||||
.setSSLSocketFactory(SSLContextBuilder
|
||||
.create()
|
||||
.setProtocol(protocol)
|
||||
.setKeyManagers(getKeyManager(certPass, certPath, null))
|
||||
.setSecureRandom(new SecureRandom())
|
||||
.build()
|
||||
.build().getSocketFactory()
|
||||
)
|
||||
.body(data)
|
||||
.execute()
|
||||
@@ -304,7 +305,7 @@ public abstract class AbstractHttpDelegate {
|
||||
* @return {@link String} 请求返回的结果
|
||||
*/
|
||||
public String post(String url, String data, String certPath, String certPass) {
|
||||
return post(url, data, certPath, certPass, SSLSocketFactoryBuilder.TLSv1);
|
||||
return post(url, data, certPath, certPass, SSLProtocols.TLSv1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -320,12 +321,12 @@ public abstract class AbstractHttpDelegate {
|
||||
public String post(String url, String data, InputStream certFile, String certPass, String protocol) {
|
||||
try {
|
||||
return HttpRequest.post(url)
|
||||
.setSSLSocketFactory(SSLSocketFactoryBuilder
|
||||
.setSSLSocketFactory(SSLContextBuilder
|
||||
.create()
|
||||
.setProtocol(protocol)
|
||||
.setKeyManagers(getKeyManager(certPass, null, certFile))
|
||||
.setSecureRandom(new SecureRandom())
|
||||
.build()
|
||||
.build().getSocketFactory()
|
||||
)
|
||||
.body(data)
|
||||
.execute()
|
||||
@@ -345,7 +346,7 @@ public abstract class AbstractHttpDelegate {
|
||||
* @return {@link String} 请求返回的结果
|
||||
*/
|
||||
public String post(String url, String data, InputStream certFile, String certPass) {
|
||||
return post(url, data, certFile, certPass, SSLSocketFactoryBuilder.TLSv1);
|
||||
return post(url, data, certFile, certPass, SSLProtocols.TLSv1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user