huliguo
2025-04-03 de40c5a7d03ffe9bcdb2aabe82e03aef98e94eb8
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
@@ -27,6 +27,7 @@
import com.ruoyi.order.mapper.OrderMapper;
import com.ruoyi.order.model.Order;
import com.ruoyi.order.model.OrderGood;
import com.ruoyi.order.service.OrderGoodService;
import com.ruoyi.order.service.OrderService;
import com.ruoyi.order.util.ExpressDeliveryUtil;
import com.ruoyi.order.util.payment.PaymentUtil;
@@ -37,7 +38,10 @@
import com.ruoyi.order.vo.*;
import com.ruoyi.other.api.domain.*;
import com.ruoyi.other.api.feignClient.*;
import com.ruoyi.other.api.vo.GetSeckillActivityInfo;
import com.ruoyi.system.api.domain.SysConfig;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.feignClient.SysConfigClient;
import com.ruoyi.system.api.feignClient.SysUserClient;
import com.ruoyi.system.api.model.LoginUser;
import lombok.SneakyThrows;
@@ -98,6 +102,14 @@
    @Resource
    private GoodsClient goodsClient;
    @Resource
    private SeckillActivityInfoClient seckillActivityInfoClient;
    @Resource
    private SysConfigClient sysConfigClient;
    @Resource
    private GoodsShopClient goodsShopClient;
    @Resource
    private OrderGoodService orderGoodService;
    @Resource
    private RedisTemplate redisTemplate;
@@ -622,16 +634,172 @@
        //用户信息
        Long userid = tokenService.getLoginUserApplet().getUserid();
        AppUser appUser = appUserClient.getAppUserById(userid);
        //商品信息
        //获取商品信息
        Goods good = goodsClient.getGoodsById(goodId).getData();
        if (null == good) {
        if (null == good||good.getDelFlag()==1||good.getStatus()==0) {
            //商品不存在
            throw new ServiceException("商品不存在");
        }
        //店铺信息
        //查询店铺信息
        //计算价格信息
        GoodsShop shop = goodsShopClient.getGoodsShop(goodId).getData();
        System.out.println(shop);
        if (null == shop){
            //门店不存在
            throw new ServiceException("该商品门店不存在");
        }
        //插入基础信息
        confirmOrderVo.setGoodId(goodId);
        confirmOrderVo.setGoodName(good.getName());
        confirmOrderVo.setHomePicture(good.getHomePagePicture());
        confirmOrderVo.setNumber(1);
        confirmOrderVo.setShopId(shop.getShopId());
        confirmOrderVo.setShopName(shop.getShopName());
        confirmOrderVo.setPurchaseLimitNum(good.getPurchaseLimit());
        confirmOrderVo.setOriginalPrice(good.getOriginalPrice());
        //todo 实时计算用户可用积分
        confirmOrderVo.setResidualPoint(appUser.getAvailablePoint());
        //插入价格
        confirmOrderVo.setCash(good.getSellingPrice());
        confirmOrderVo.setPoint(good.getIntegral());
        //计算活动价格信息
        Price price = getPrice(goodId, 1);
        if (null != price) {
            confirmOrderVo.setCash(price.getCash());
            confirmOrderVo.setOrderPoint(price.getPoint());
            confirmOrderVo.setEndTimeStamp(price.getEndTimeStamp());
        }
        //判断是否是积分支付
        if (type == 1) {//现金
            confirmOrderVo.setOrderMoney(confirmOrderVo.getCash());
            //计算积分抵扣的金额  将积分转为金额,去掉小数
            BigDecimal deduction=getCashByPoint(confirmOrderVo.getResidualPoint());
            confirmOrderVo.setDeduction(deduction);
        }else {//积分
            confirmOrderVo.setOrderPoint(good.getIntegral());
        }
        //限购检查
        //判断当前数量是否已经超出限购数量(需要计算已经购买的数量)
        if(null == good.getPurchaseLimit() || -1 == good.getPurchaseLimit()){
            confirmOrderVo.setIsPurchaseLimit(false);
            confirmOrderVo.setPurchaseLimitNum(-1);
        }else{
            //todo 查当前用户的订单
            List<Order> orders = this.list(new LambdaQueryWrapper<Order>().eq(Order::getAppUserId, appUser.getId()).eq(Order::getDelFlag, 0).in(Order::getOrderStatus, Arrays.asList(4, 8)));
            List<Long> orderIds = orders.stream().map(Order::getId).collect(Collectors.toList());
            int sum = 0;
            if(!orderIds.isEmpty()){
                //关于该商品的订单
                List<OrderGood> orderGoodList = orderGoodService.list(new LambdaQueryWrapper<OrderGood>().in(OrderGood::getOrderId, orderIds)
                        .eq(OrderGood::getGoodsId, good.getId()).eq(OrderGood::getDelFlag, 0));
                sum = orderGoodList.stream().mapToInt(OrderGood::getNum).sum();
            }
            confirmOrderVo.setIsPurchaseLimit((1 + sum) > good.getPurchaseLimit());
            confirmOrderVo.setPurchaseLimitNum(good.getPurchaseLimit() - sum);
        }
        return confirmOrderVo;
    }
    /**
     * 根据商品的价格配置体系获取商品当前的价格
     * @param goodsId
     * @param type          1普通商品,2秒杀商品
     * @return
     */
    public Price getPrice( Integer goodsId, Integer type){
        //判断是否有在秒杀活动时间中
        Price price = new Price();
        GetSeckillActivityInfo getSeckillActivityInfo = new GetSeckillActivityInfo();
        getSeckillActivityInfo.setGoodsId(goodsId);
        GoodsSeckill goodsSeckill = seckillActivityInfoClient.getSeckillActivityInfo(getSeckillActivityInfo).getData();
        //没有秒杀活动或者添加的普通商品则使用秒杀活动价格
        if(null == goodsSeckill || type == 1){
            return null;
        }
        //秒杀活动价格
        price.setCash(goodsSeckill.getSellingPrice());
        //计算对应积分
        price.setPoint(getPoint(price.getCash()));
        price.setEndTimeStamp(goodsSeckill.getEndTime());
        return price;
    }
    /**
     * 获取现金对应积分
     */
    public Integer getPoint(BigDecimal cash){
        if (cash == null || cash.compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("金额不能为null或负数");
        }
        // 获取积分兑换比例配置
        R<SysConfig> info = sysConfigClient.getInfo(6L);
        if (info == null || info.getData() == null) {
            throw new RuntimeException("获取积分兑换比例配置失败");
        }
        String configValue = info.getData().getConfigValue();
        if (StringUtils.isBlank(configValue)) {
            throw new RuntimeException("积分兑换比例配置值为空");
        }
        try {
            // 使用BigDecimal处理比例,避免精度问题
            BigDecimal ratio = new BigDecimal(configValue.trim());
            if (ratio.compareTo(BigDecimal.ZERO) <= 0) {
                throw new RuntimeException("积分兑换比例必须大于0");
            }
            // 计算积分并四舍五入取整
            return cash.multiply(ratio).intValue();
        } catch (NumberFormatException e) {
            throw new RuntimeException("积分兑换比例配置值格式错误", e);
        } catch (ArithmeticException e) {
            throw new RuntimeException("积分计算结果溢出", e);
        }
    }
    /**
     * 获取积分对应金额
     */
    public BigDecimal getCashByPoint(Integer point){
        // 参数校验
        if (point == null || point < 0) {
            throw new IllegalArgumentException("积分值不能为null或负数");
        }
        // 特殊情况:0积分直接返回0金额
        if (point == 0) {
            return BigDecimal.ZERO.setScale(2);
        }
        // 获取积分兑换比例配置
        R<SysConfig> info = sysConfigClient.getInfo(6L);
        if (info == null || info.getData() == null) {
            throw new RuntimeException("获取积分兑换比例配置失败");
        }
        String configValue = info.getData().getConfigValue(); // 示例:"100" 表示 100积分=1元
        if (StringUtils.isBlank(configValue)) {
            throw new RuntimeException("积分兑换比例配置值为空");
        }
        try {
            // 解析兑换比例(转换为BigDecimal保证精度)
            BigDecimal exchangeRate = new BigDecimal(configValue.trim());
            if (exchangeRate.compareTo(BigDecimal.ZERO) <= 0) {
                throw new RuntimeException("积分兑换比例必须为正数");
            }
            // 高精度计算(积分/比例)
            return new BigDecimal(point)
                    .divide(exchangeRate, 2, RoundingMode.HALF_UP);
        } catch (NumberFormatException e) {
            throw new RuntimeException("积分兑换比例配置值格式错误,应为数字", e);
        } catch (ArithmeticException e) {
            throw new RuntimeException("积分计算错误", e);
        }
    }
}