rk
5 天以前 74b0af6814b96378201ea27d205e054bf01d0306
server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java
@@ -420,8 +420,11 @@
        String to = dto.getToLat() + "," + dto.getToLgt();
        JSONObject distanceResult = MapUtil.direction("driving", from, to);
        BigDecimal distance = distanceResult.getBigDecimal("distance");
        // distance 单位为米,转为公里
        // distance 单位为米,转为公里(不足1公里按1公里计算)
        BigDecimal distanceKm = distance.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP);
        if (distanceKm.compareTo(BigDecimal.ONE) < 0) {
            distanceKm = BigDecimal.ONE;
        }
        // 收集所有物品类型ID
        List<Integer> categoryIds = new ArrayList<>();
@@ -645,8 +648,11 @@
        // ========== 3. 查询寄件店铺信息 ==========
        ShopInfo depositShop = shopInfoMapper.selectById(dto.getDepositShopId());
        if (depositShop == null) {
        if (depositShop == null || Constants.equalsInteger(depositShop.getDeleted(), Constants.ONE)) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "寄件店铺不存在");
        }
        if (depositShop.getStatus() == null || !Constants.equalsInteger(depositShop.getStatus(), Constants.ZERO)) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "寄件店铺已停业,请选择其他门店");
        }
        // ========== 4. 计算费用 ==========
@@ -663,9 +669,15 @@
            }
            // 取件点:店铺 or 自选点,至少提供一组
            if (dto.getTakeShopId() != null) {
                if (dto.getTakeShopId().equals(dto.getDepositShopId())) {
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "异地寄存订单存件门店和取件门店不能相同");
                }
                takeShop = shopInfoMapper.selectById(dto.getTakeShopId());
                if (takeShop == null) {
                if (takeShop == null || Constants.equalsInteger(takeShop.getDeleted(), Constants.ONE)) {
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "取件店铺不存在");
                }
                if (takeShop.getStatus() == null || !Constants.equalsInteger(takeShop.getStatus(), Constants.ONE)) {
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "取件店铺已停业,请选择其他门店");
                }
                takeLat = BigDecimal.valueOf(takeShop.getLatitude());
                takeLgt = BigDecimal.valueOf(takeShop.getLongitude());
@@ -764,6 +776,7 @@
            orders.setTakeLat(takeLat);
            orders.setTakeLgt(takeLgt);
            orders.setIsUrgent(dto.getIsUrgent());
            orders.setDistance(priceResult.getDistance());
        } else {
            // 就地:取件点同寄件店铺
            orders.setTakeShopId(dto.getDepositShopId());
@@ -775,7 +788,12 @@
        // 物品信息
        orders.setGoodType(dto.getGoodType());
        orders.setGoodLevel(goodTypeCategory.getRelationId());
        // 查询物品级别 type = 3
        Category levelCategory = categoryMapper.selectById(goodTypeCategory.getRelationId());
        if(Objects.isNull(levelCategory)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"未查询到物品等级信息:{}"+goodTypeCategory.getName());
        }
        orders.setGoodLevel(Integer.valueOf(levelCategory.getDetail()));
        // 拼接物品信息:物品类型名称、尺寸名称*数量(数组字符串)
        List<String> goodsParts = new ArrayList<>();
        for (ItemPriceVO itemVO : priceResult.getItemList()) {
@@ -797,7 +815,6 @@
        }
        orders.setDeclaredFee(priceResult.getInsuranceFee());
        orders.setPrice(priceResult.getItemPrice());
        // 薪酬计算与占比存储
        calculateAndSetFeeAllocation(orders, depositShop, takeShop);
@@ -1307,8 +1324,9 @@
                .eq(PricingRule::getCityId, cityId)
                .eq(PricingRule::getFieldA, String.valueOf(fieldA))
                .last("limit 1"));
        if (rule != null && StringUtils.isNotBlank(rule.getFieldC())) {
            return new BigDecimal(rule.getFieldC());
        if (rule != null && StringUtils.isNotBlank(rule.getFieldB())) {
            // fieldB 存储的是百分比整数(如15表示15%),转换为小数比例(0.15)
            return new BigDecimal(rule.getFieldB()).divide(new BigDecimal("100"), 4, BigDecimal.ROUND_HALF_UP);
        }
        return BigDecimal.ZERO;
    }
@@ -1836,6 +1854,7 @@
        order.setPayStatus(Constants.ONE); // 已支付
        order.setPayTime(now);
        order.setWxExternalNo(wxTradeNo);
        order.setPayAmount(order.getTotalAmount());
        order.setUpdateTime(now);
        // 生成会员核销码
        order.setMemberVerifyCode(generateVerifyCode());
@@ -1981,9 +2000,10 @@
    @Override
    @Transactional(rollbackFor = {Exception.class, BusinessException.class})
    public PayResponse payShopDeposit(Integer shopId) {
    public PayResponse payShopDeposit(Integer memberId) {
        // 1. 查询门店信息
        ShopInfo shopInfo = shopInfoMapper.selectById(shopId);
        ShopInfo shopInfo = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda()
                .eq(ShopInfo::getRegionMemberId,memberId));
        if (shopInfo == null) {
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "门店不存在");
        }
@@ -2007,7 +2027,7 @@
        otherOrders.setMemberId(shopInfo.getRegionMemberId());
        otherOrders.setPayAccount(shopInfo.getDepositAmount());
        otherOrders.setPayStatus(Constants.ZERO);
        otherOrders.setCode("SD" + new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(now) + shopId);
        otherOrders.setCode("SD" + new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(now) + shopInfo.getId());
        otherOrders.setOutTradeNo(outTradeNo);
        otherOrders.setDeleted(Constants.ZERO);
        otherOrders.setCreateTime(now);
@@ -3121,6 +3141,61 @@
    }
    @Override
    public ActiveOrderTipVO getActiveOrderTip(Integer memberId) {
        // 查询状态为 0~5 的最新一条订单
        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
        wrapper.eq("MEMBER_ID", memberId)
                .in("STATUS", 0, 1, 2, 3, 4, 5)
                .orderByDesc("CREATE_TIME")
                .last("LIMIT 1");
        Orders order = ordersMapper.selectOne(wrapper);
        if (order == null) {
            return null;
        }
        ActiveOrderTipVO vo = new ActiveOrderTipVO();
        vo.setOrderId(order.getId());
        vo.setStatus(order.getStatus());
        // 构建提示文案
        boolean isLocal = Constants.equalsInteger(order.getType(), Constants.ZERO);
        Integer status = order.getStatus();
        String tip = null;
        if (Constants.equalsInteger(status, Constants.OrderStatus.waitPay.getStatus())) {
            // 待支付:提示支付倒计时
            String minutes = "";
            try {
                minutes = operationConfigBiz.getConfig().getAutoCancelTime();
            } catch (Exception ignored) {}
            tip = "请在" + (StringUtils.isNotBlank(minutes) ? minutes : "") + "分钟内完成支付,超时订单将自动取消";
            // 计算支付倒计时
            if (StringUtils.isNotBlank(minutes) && order.getCreateTime() != null) {
                long timeoutMs = Long.parseLong(minutes) * 60 * 1000;
                long deadline = order.getCreateTime().getTime() + timeoutMs;
                long remain = deadline - System.currentTimeMillis();
                vo.setPayCountdown(remain > 0 ? remain : -1L);
            } else {
                vo.setPayCountdown(-1L);
            }
        } else if (Constants.equalsInteger(status, Constants.OrderStatus.waitDeposit.getStatus())) {
            tip = "订单已支付,请前往门店寄存";
        } else if (Constants.equalsInteger(status, Constants.OrderStatus.deposited.getStatus())) {
            tip = isLocal ? "行李已寄存,请凭取件码前往指定门店取件" : "门店已接单,正在为您安排取件司机";
        } else if (Constants.equalsInteger(status, Constants.OrderStatus.accepted.getStatus())) {
            tip = isLocal ? "行李已寄存,请凭取件码前往指定门店取件" : "已有司机抢单,正前往取件地点";
        } else if (Constants.equalsInteger(status, Constants.OrderStatus.delivering.getStatus())) {
            tip = "司机已取件,正运往目的地";
        } else if (Constants.equalsInteger(status, Constants.OrderStatus.arrived.getStatus())) {
            tip = "行李已送达服务点,请及时前往取件";
        }
        vo.setTip(tip);
        return vo;
    }
    @Override
    public EstimatedDeliveryResultVO calculateEstimatedDelivery(Integer cityId,
                                                                Double fromLat, Double fromLng,
                                                                Double toLat, Double toLng) {