|
@@ -1,29 +1,28 @@
|
|
|
package com.fs.his.service.impl;
|
|
package com.fs.his.service.impl;
|
|
|
|
|
|
|
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.fs.common.core.domain.R;
|
|
import com.fs.common.core.domain.R;
|
|
|
import com.fs.common.exception.CustomException;
|
|
import com.fs.common.exception.CustomException;
|
|
|
import com.fs.common.exception.ServiceException;
|
|
import com.fs.common.exception.ServiceException;
|
|
|
-import com.fs.his.domain.FsIntegralCart;
|
|
|
|
|
-import com.fs.his.domain.FsIntegralGoods;
|
|
|
|
|
-import com.fs.his.domain.FsUser;
|
|
|
|
|
-import com.fs.his.domain.FsUserAddress;
|
|
|
|
|
-import com.fs.his.mapper.FsIntegralCartMapper;
|
|
|
|
|
-import com.fs.his.mapper.FsIntegralGoodsMapper;
|
|
|
|
|
-import com.fs.his.mapper.FsUserAddressMapper;
|
|
|
|
|
-import com.fs.his.mapper.FsUserMapper;
|
|
|
|
|
|
|
+import com.fs.common.utils.StringUtils;
|
|
|
|
|
+import com.fs.common.utils.spring.SpringUtils;
|
|
|
|
|
+import com.fs.core.utils.OrderCodeUtils;
|
|
|
|
|
+import com.fs.his.domain.*;
|
|
|
|
|
+import com.fs.his.mapper.*;
|
|
|
import com.fs.his.param.AddGoodsIntoCartParam;
|
|
import com.fs.his.param.AddGoodsIntoCartParam;
|
|
|
|
|
+import com.fs.his.param.CreateOrderFromCartParm;
|
|
|
import com.fs.his.param.GetFsIntegralCartDetailsParm;
|
|
import com.fs.his.param.GetFsIntegralCartDetailsParm;
|
|
|
import com.fs.his.param.GetFsIntegralCartListParam;
|
|
import com.fs.his.param.GetFsIntegralCartListParam;
|
|
|
import com.fs.his.service.IFsIntegralCartService;
|
|
import com.fs.his.service.IFsIntegralCartService;
|
|
|
-import com.fs.his.vo.FsIntegralCartVO;
|
|
|
|
|
-import com.fs.his.vo.GetCartGoodsDetailsVo;
|
|
|
|
|
-import com.fs.his.vo.GetFsIntegralCartDetailsVo;
|
|
|
|
|
-import com.fs.his.vo.GetFsIntegralCartListVo;
|
|
|
|
|
|
|
+import com.fs.his.service.IFsUserIntegralLogsService;
|
|
|
|
|
+import com.fs.his.vo.*;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.ObjectUtils;
|
|
import org.apache.commons.lang3.ObjectUtils;
|
|
|
|
|
+import org.redisson.api.RLock;
|
|
|
|
|
+import org.redisson.api.RedissonClient;
|
|
|
import org.springframework.beans.BeanUtils;
|
|
import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.dao.DuplicateKeyException;
|
|
import org.springframework.dao.DuplicateKeyException;
|
|
@@ -34,6 +33,8 @@ import javax.annotation.Resource;
|
|
|
import javax.validation.constraints.NotNull;
|
|
import javax.validation.constraints.NotNull;
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
@Slf4j
|
|
@Slf4j
|
|
|
@Service
|
|
@Service
|
|
@@ -44,12 +45,24 @@ public class FsIntegralCartServiceImpl extends ServiceImpl<FsIntegralCartMapper,
|
|
|
@Resource
|
|
@Resource
|
|
|
private FsUserMapper userMapper;
|
|
private FsUserMapper userMapper;
|
|
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private FsUserMapper fsUserMapper;
|
|
|
|
|
+
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private FsUserAddressMapper fsUserAddressMapper;
|
|
private FsUserAddressMapper fsUserAddressMapper;
|
|
|
|
|
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private FsIntegralGoodsMapper fsIntegralGoodsMapper;
|
|
private FsIntegralGoodsMapper fsIntegralGoodsMapper;
|
|
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private FsIntegralCartMapper fsIntegralCartMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private FsIntegralOrderMapper fsIntegralOrderMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ IFsUserIntegralLogsService integralLogsService;
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 添加或修改购物车
|
|
* 添加或修改购物车
|
|
|
*
|
|
*
|
|
@@ -165,7 +178,7 @@ public class FsIntegralCartServiceImpl extends ServiceImpl<FsIntegralCartMapper,
|
|
|
for (GetFsIntegralCartListVo listVo : cartListVoList) {
|
|
for (GetFsIntegralCartListVo listVo : cartListVoList) {
|
|
|
GetCartGoodsDetailsVo cartListVo = new GetCartGoodsDetailsVo();
|
|
GetCartGoodsDetailsVo cartListVo = new GetCartGoodsDetailsVo();
|
|
|
BeanUtils.copyProperties(listVo, cartListVo);
|
|
BeanUtils.copyProperties(listVo, cartListVo);
|
|
|
- cartListVo.setGoodsIntegralTotal(listVo.getGoodsIntegral() * listVo.getQuantity());
|
|
|
|
|
|
|
+ cartListVo.setGoodsIntegralTotal(listVo.getGoodsIntegral() * listVo.getCartNum());
|
|
|
goodsDetailsVos.add(cartListVo);
|
|
goodsDetailsVos.add(cartListVo);
|
|
|
}
|
|
}
|
|
|
if (ObjectUtils.isNotEmpty(param.getAddressId())) {
|
|
if (ObjectUtils.isNotEmpty(param.getAddressId())) {
|
|
@@ -230,4 +243,106 @@ public class FsIntegralCartServiceImpl extends ServiceImpl<FsIntegralCartMapper,
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R createOrderFromCart(CreateOrderFromCartParm param, Long userId) {
|
|
|
|
|
+ RedissonClient redissonClient = SpringUtils.getBean(RedissonClient.class);
|
|
|
|
|
+ String lockKey = "fsIntegralCartOrderCreate:" + userId;
|
|
|
|
|
+ RLock lock = redissonClient.getLock(lockKey);
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 尝试获取锁,最多等待3秒,持有锁时间最多30秒
|
|
|
|
|
+ boolean isLocked = lock.tryLock(3, 10, TimeUnit.SECONDS);
|
|
|
|
|
+ if (!isLocked) {
|
|
|
|
|
+ return R.error("系统繁忙,请稍后再试");
|
|
|
|
|
+ }
|
|
|
|
|
+ FsUser user = fsUserMapper.selectFsUserByUserId(userId);
|
|
|
|
|
+ FsUserAddress address = fsUserAddressMapper.selectFsUserAddressByAddressId(param.getAddressId());
|
|
|
|
|
+ List<FsIntegralGoodsVo> fsIntegralGoods = fsIntegralGoodsMapper.selectAllByGoodsIds(new HashSet<>(param.getGoodsId()));
|
|
|
|
|
+ List<FsIntegralCart> existingCart = fsIntegralCartMapper.selectList(Wrappers.<FsIntegralCart>lambdaQuery().eq(FsIntegralCart::getUserId, userId).in(FsIntegralCart::getGoodsId, param.getGoodsId()));
|
|
|
|
|
+ Map<Long, Integer> collect = existingCart.stream().collect(Collectors.groupingBy(FsIntegralCart::getGoodsId, Collectors.summingInt(FsIntegralCart::getCartNum)));
|
|
|
|
|
+ StringBuilder quantity = new StringBuilder();
|
|
|
|
|
+ for (FsIntegralGoodsVo fsIntegralGood : fsIntegralGoods) {
|
|
|
|
|
+ Integer integer = collect.get(fsIntegralGood.getGoodsId());
|
|
|
|
|
+ if (fsIntegralGood.getStock() < integer) {
|
|
|
|
|
+ throw new ServiceException(String.format("%d库存不足,兑换失败", fsIntegralGood.getGoodsName()));
|
|
|
|
|
+ }
|
|
|
|
|
+ if (fsIntegralGood.getStatus() != 1) {
|
|
|
|
|
+ this.remove(Wrappers.<FsIntegralCart>lambdaQuery().eq(FsIntegralCart::getUserId, userId).eq(FsIntegralCart::getGoodsId, fsIntegralGood.getGoodsId()));
|
|
|
|
|
+ log.info("清除下架商品,userId:{}, goodsId:{}", userId, fsIntegralGood.getGoodsId());
|
|
|
|
|
+ throw new ServiceException(String.format("商品[名称:%d]已下架,兑换失败", fsIntegralGood.getGoodsName()));
|
|
|
|
|
+ }
|
|
|
|
|
+ fsIntegralGood.setIntegralByNum(integer * fsIntegralGood.getIntegral());
|
|
|
|
|
+ fsIntegralGood.setQuantity(integer);
|
|
|
|
|
+ if (quantity.length() > 0) {
|
|
|
|
|
+ quantity.append(",");
|
|
|
|
|
+ }
|
|
|
|
|
+ quantity.append(ObjectUtils.isNotEmpty(integer) ? integer : "0");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 商品总的积分
|
|
|
|
|
+ Long goodsIntegral = fsIntegralGoods.stream().filter(n -> ObjectUtils.isNotEmpty(n.getIntegralByNum())).mapToLong(FsIntegralGoodsVo::getIntegralByNum).sum();
|
|
|
|
|
+ if (user.getIntegral() < goodsIntegral) {
|
|
|
|
|
+ throw new ServiceException("用户积分不足,兑换失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ String barCode = fsIntegralGoods.stream().map(FsIntegralGoodsVo::getBarCode).collect(Collectors.joining(","));
|
|
|
|
|
+ String Integral = fsIntegralGoods.stream().map(m -> m.getIntegral().toString()).collect(Collectors.joining(","));
|
|
|
|
|
+// String orderSn = OrderCodeUtils.getOrderSn();
|
|
|
|
|
+ String orderSn = "6666666666666666666666";
|
|
|
|
|
+ if (StringUtils.isEmpty(orderSn)) {
|
|
|
|
|
+ throw new ServiceException("订单生成失败,请重试");
|
|
|
|
|
+ }
|
|
|
|
|
+ FsIntegralOrder order = new FsIntegralOrder();
|
|
|
|
|
+ order.setOrderCode(orderSn);
|
|
|
|
|
+ order.setUserId(user.getUserId());
|
|
|
|
|
+ order.setStatus(1);
|
|
|
|
|
+ order.setBarCodeCart(barCode);
|
|
|
|
|
+ order.setIntegral(goodsIntegral.toString());
|
|
|
|
|
+ order.setIntegralByCart(Integral);
|
|
|
|
|
+ order.setItemJson(ObjectUtils.isNotEmpty(fsIntegralGoods) ? JSONUtil.toJsonStr(fsIntegralGoods) : null);
|
|
|
|
|
+ order.setItemCartJson(ObjectUtils.isNotEmpty(fsIntegralGoods) ? JSONUtil.toJsonStr(fsIntegralGoods) : null);
|
|
|
|
|
+ order.setUserName(address.getRealName());
|
|
|
|
|
+ order.setUserAddress(address.getProvince() + address.getCity() + address.getDistrict() + address.getDetail());
|
|
|
|
|
+ order.setUserPhone(address.getPhone());
|
|
|
|
|
+ order.setCreateTime(new Date());
|
|
|
|
|
+ order.setQuantityCart(quantity.toString());
|
|
|
|
|
+ if (fsIntegralOrderMapper.insertFsIntegralOrder(order) > 0) {
|
|
|
|
|
+ //写入日志
|
|
|
|
|
+ FsUser userMap = new FsUser();
|
|
|
|
|
+ userMap.setUserId(user.getUserId());
|
|
|
|
|
+ // 可消费积分
|
|
|
|
|
+ long consumer = user.getIntegral() - user.getWithdrawIntegral();
|
|
|
|
|
+ if (consumer < goodsIntegral) {
|
|
|
|
|
+ // 扣除完可消费积分后,剩余的积分
|
|
|
|
|
+ long extra = goodsIntegral - consumer;
|
|
|
|
|
+ // 可提现积分扣除 剩余积分
|
|
|
|
|
+ Long withdrawIntegral = user.getWithdrawIntegral() - extra;
|
|
|
|
|
+ userMap.setIntegral(withdrawIntegral);
|
|
|
|
|
+ userMap.setWithdrawIntegral(withdrawIntegral);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ userMap.setIntegral(user.getIntegral() - goodsIntegral);
|
|
|
|
|
+ }
|
|
|
|
|
+ fsUserMapper.updateFsUser(userMap);
|
|
|
|
|
+ FsUserIntegralLogs logs = new FsUserIntegralLogs();
|
|
|
|
|
+ logs.setIntegral(-goodsIntegral);
|
|
|
|
|
+ logs.setUserId(order.getUserId());
|
|
|
|
|
+ logs.setBalance(userMap.getIntegral());
|
|
|
|
|
+ logs.setLogType(5);
|
|
|
|
|
+ logs.setBusinessId(order.getOrderId().toString());
|
|
|
|
|
+ logs.setCreateTime(new Date());
|
|
|
|
|
+ logs.setNickName(user.getNickName());
|
|
|
|
|
+ logs.setPhone(user.getPhone());
|
|
|
|
|
+ integralLogsService.insertFsUserIntegralLogs(logs);
|
|
|
|
|
+ //清空购物车对应商品
|
|
|
|
|
+ this.remove(Wrappers.<FsIntegralCart>lambdaQuery().eq(FsIntegralCart::getUserId, userId).in(FsIntegralCart::getGoodsId, param.getGoodsId()));
|
|
|
|
|
+ return R.ok("兑换成功").put("order", order);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return R.error("订单创建失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ return R.error(e.getMessage());
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ if (lock.isHeldByCurrentThread()) {
|
|
|
|
|
+ lock.unlock();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|