rk
2 天以前 761d13616d43b147142d7d33da3a646f6ac15397
server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java
@@ -17,6 +17,7 @@
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.core.utils.DateUtil;
import com.doumee.core.utils.ID;
import com.doumee.core.utils.geocode.MapUtil;
import com.doumee.core.utils.Utils;
import com.doumee.core.utils.aliyun.AliSmsService;
@@ -237,7 +238,14 @@
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        return PageData.from(ordersMapper.selectJoinPage(page, Orders.class, queryWrapper));
        PageData<Orders> pageData = PageData.from(ordersMapper.selectJoinPage(page, Orders.class, queryWrapper));
        for (Orders o : pageData.getRecords()) {
            if (o.getStatus() != null) {
                Constants.OrderStatus os = Constants.OrderStatus.getByKey(o.getStatus());
                o.setStatusDesc(os != null ? os.getValue() : "");
            }
        }
        return pageData;
    }
    @Override
@@ -698,7 +706,7 @@
                // 无取件门店,校验存件点与自选取件点是否在同一城市
                if (!MapUtil.isSameCity(depositShop.getLatitude(), depositShop.getLongitude(),
                        dto.getTakeLat().doubleValue(), dto.getTakeLgt().doubleValue())) {
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "异地寄存订单存取点不在同一城市,如需请选择同城门店");
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "存取点不在同一城市!");
                }
                takeLat = dto.getTakeLat();
                takeLgt = dto.getTakeLgt();
@@ -785,6 +793,7 @@
            // 异地:取件点信息
            orders.setTakeShopId(dto.getTakeShopId());
            orders.setTakeLocation(takeLocationValue);
            orders.setTakeLocationRemark(takeLocationValue);
            orders.setTakeLat(takeLat);
            orders.setTakeLgt(takeLgt);
            orders.setIsUrgent(dto.getIsUrgent());
@@ -793,6 +802,7 @@
            // 就地:取件点同寄件店铺
            orders.setTakeShopId(dto.getDepositShopId());
            orders.setTakeLocation(depositShop.getAddress());
            orders.setTakeLocationRemark(depositShop.getAddress());
            orders.setTakeLat(BigDecimal.valueOf(depositShop.getLatitude()));
            orders.setTakeLgt(BigDecimal.valueOf(depositShop.getLongitude()));
            orders.setIsUrgent(Constants.ZERO);
@@ -836,6 +846,19 @@
        ordersMapper.insert(orders);
        Integer orderId = orders.getId();
        // 创建订单日志
        OrderLog createLog = new OrderLog();
        createLog.setOrderId(orderId);
        createLog.setTitle(Constants.OrderLogType.createOrder.getTitle());
        createLog.setLogInfo(Constants.OrderLogType.createOrder.format(orderCode));
        createLog.setObjType(Constants.OrderLogType.createOrder.getStatus());
        createLog.setOrderStatus(orders.getStatus());
        createLog.setOptUserId(memberId);
        createLog.setOptUserType(0);
        createLog.setCreateTime(now);
        createLog.setDeleted(Constants.ZERO);
        orderLogService.create(createLog);
        // ========== 7. 创建订单明细 ==========
        for (ItemPriceVO itemVO : priceResult.getItemList()) {
@@ -987,6 +1010,12 @@
        OrderDetailVO vo = new OrderDetailVO();
        vo.setOrder(order);
        // 订单状态描述
        if (order.getStatus() != null) {
            Constants.OrderStatus os = Constants.OrderStatus.getByKey(order.getStatus());
            vo.setStatusDesc(os != null ? os.getValue() : "");
        }
        // 图片路径前缀
        String imgPrefix = getOrdersPrefix();
@@ -1111,19 +1140,6 @@
        String optUserName = getCurrentUserName();
        // 加急费日志
        OrderLog feeLog = new OrderLog();
        feeLog.setOrderId(order.getId());
        feeLog.setTitle(Constants.OrderLogType.urgent.getTitle());
        feeLog.setLogInfo(Constants.OrderLogType.urgent.format(dto.getUrgentFee().toPlainString()));
        feeLog.setObjType(Constants.OrderLogType.urgent.getStatus());
        feeLog.setOrderStatus(order.getStatus());
        feeLog.setOptUserType(3);
        feeLog.setOptUserName(optUserName);
        feeLog.setCreateTime(new Date());
        feeLog.setDeleted(Constants.ZERO);
        orderLogService.create(feeLog);
        // 加急费用 元→分
        long urgentFeeFen = dto.getUrgentFee().multiply(new BigDecimal(100)).longValue();
@@ -1148,9 +1164,30 @@
            updateWrapper.set(Orders::getRemark, dto.getRemark());
        }
        // 指派司机(非必填)
        // 日志:只存一条,有司机用 assignDriver,无司机用 urgent
        if (dto.getDriverId() != null) {
            // 校验司机信息
            DriverInfo driverInfo = driverInfoMapper.selectOne(new QueryWrapper<DriverInfo>().lambda()
                    .eq(DriverInfo::getMemberId, dto.getDriverId())
                    .eq(DriverInfo::getDeleted, Constants.ZERO)
                    .last("limit 1"));
            if (driverInfo == null) {
                throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "司机信息不存在");
            }
            if (!Integer.valueOf(3).equals(driverInfo.getAuditStatus())) {
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "司机未支付押金,无法派单");
            }
            if (!Constants.ZERO.equals(driverInfo.getStatus())) {
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "司机已被禁用,无法派单");
            }
            // 更新接单司机信息及订单状态
            Date now = new Date();
            updateWrapper.set(Orders::getAssignDriverId, dto.getDriverId());
            updateWrapper.set(Orders::getAcceptDriver, dto.getDriverId());
            updateWrapper.set(Orders::getAcceptTime, now);
            updateWrapper.set(Orders::getAcceptType, 1); // 1=系统派单
            updateWrapper.set(Orders::getStatus, Constants.OrderStatus.accepted.getStatus());
            Member driver = memberMapper.selectById(dto.getDriverId());
            String driverName = driver != null ? driver.getName() : String.valueOf(dto.getDriverId());
@@ -1160,32 +1197,37 @@
            driverLog.setTitle(Constants.OrderLogType.assignDriver.getTitle());
            driverLog.setLogInfo(Constants.OrderLogType.assignDriver.format(driverName, dto.getUrgentFee().toPlainString()));
            driverLog.setObjType(Constants.OrderLogType.assignDriver.getStatus());
            driverLog.setOrderStatus(order.getStatus());
            driverLog.setOrderStatus(Constants.OrderStatus.accepted.getStatus());
            driverLog.setOptUserType(3);
            driverLog.setOptUserName(optUserName);
            driverLog.setCreateTime(new Date());
            driverLog.setCreateTime(now);
            driverLog.setDeleted(Constants.ZERO);
            orderLogService.create(driverLog);
            // 短信通知指派司机(加急派单)
            DriverInfo driverInfo = driverInfoMapper.selectOne(new QueryWrapper<DriverInfo>().lambda()
                    .eq(DriverInfo::getMemberId, dto.getDriverId())
                    .eq(DriverInfo::getDeleted, Constants.ZERO)
                    .last("limit 1"));
            if (driverInfo != null) {
                String address1 = order.getDepositShopAddress() != null ? order.getDepositShopAddress() : order.getDepositShopName();
                String address2 = order.getTakeShopAddress() != null ? order.getTakeShopAddress() :
                        (order.getTakeLocation() != null ? order.getTakeLocation() : "");
                // 配送费 = 司机配送费 + 加急费
                long totalDriverFee = (order.getDriverFee() != null ? order.getDriverFee() : 0L) + urgentFeeFen;
                sendSmsNotify(driverInfo.getTelephone(),
                        Constants.SmsNotify.DRIVER_URGENT_DISPATCH,
                        "orderNo", order.getCode(),
                        "address1", address1,
                        "address2", address2,
                        "money1", String.valueOf(totalDriverFee / 100.0),
                        "money2", String.valueOf(urgentFeeFen / 100.0));
            }
            String address1 = order.getDepositLocationRemark();
            String address2 = order.getTakeLocationRemark();
            long totalDriverFee = (order.getDriverFee() != null ? order.getDriverFee() : 0L) + urgentFeeFen;
            sendSmsNotify(driverInfo.getTelephone(),
                    Constants.SmsNotify.DRIVER_URGENT_DISPATCH,
                    "orderNo", order.getCode(),
                    "address1", address1,
                    "address2", address2,
                    "money1", String.valueOf(totalDriverFee / 100.0),
                    "money2", String.valueOf(urgentFeeFen / 100.0));
        } else {
            // 未指派司机,只记录加急日志
            OrderLog feeLog = new OrderLog();
            feeLog.setOrderId(order.getId());
            feeLog.setTitle(Constants.OrderLogType.urgent.getTitle());
            feeLog.setLogInfo(Constants.OrderLogType.urgent.format(dto.getUrgentFee().toPlainString()));
            feeLog.setObjType(Constants.OrderLogType.urgent.getStatus());
            feeLog.setOrderStatus(order.getStatus());
            feeLog.setOptUserType(3);
            feeLog.setOptUserName(optUserName);
            feeLog.setCreateTime(new Date());
            feeLog.setDeleted(Constants.ZERO);
            orderLogService.create(feeLog);
        }
        ordersMapper.update(updateWrapper);
@@ -1888,9 +1930,10 @@
                    Constants.SmsNotify.MEMBER_CANCELLED, "orderNo", order.getCode());
            // 调用微信退款V3,全额退款
            String outRefundNo = ID.nextGUID();
            com.wechat.pay.java.service.refund.model.Refund refundResult;
            try {
                refundResult = wxPayV3Service.refund(order.getOutTradeNo(), order.getPayAmount(), order.getPayAmount(),
                refundResult = wxPayV3Service.refund(outRefundNo, order.getOutTradeNo(), order.getPayAmount(), order.getPayAmount(),
                        "订单退款", wxPayProperties.getV3RefundNotifyUrl());
            } catch (Exception e) {
                log.error("待寄存订单退款调用异常, orderId={}", orderId, e);
@@ -1908,7 +1951,7 @@
            refund.setDeleted(Constants.ZERO);
            refund.setBeforeStatus(Constants.OrderStatus.waitDeposit.getStatus());
            refund.setRefundAmount(order.getPayAmount());
            refund.setRefundCode(refundResult.getOutRefundNo());
            refund.setRefundCode(outRefundNo);
            if (com.wechat.pay.java.service.refund.model.Status.SUCCESS.equals(refundStatus)) {
                // 退款成功
@@ -2117,6 +2160,20 @@
            }
        }
        ordersMapper.updateById(order);
        // 支付成功日志
        OrderLog payLog = new OrderLog();
        payLog.setOrderId(order.getId());
        payLog.setTitle(Constants.OrderLogType.payOrder.getTitle());
        payLog.setLogInfo(Constants.OrderLogType.payOrder.format(
                String.valueOf(order.getTotalAmount() != null ? order.getTotalAmount() / 100.0 : 0)));
        payLog.setObjType(Constants.OrderLogType.payOrder.getStatus());
        payLog.setOrderStatus(order.getStatus());
        payLog.setOptUserId(order.getMemberId());
        payLog.setOptUserType(0);
        payLog.setCreateTime(now);
        payLog.setDeleted(Constants.ZERO);
        orderLogService.create(payLog);
        // 通知会员:订单待核验
        sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_VERIFY, order.getId(),
@@ -2736,7 +2793,64 @@
                        "orderNo", order.getCode(),
                        "settleDays", settleDays != null ? settleDays : "7");
            }
        } else {
        }else if(Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.delivering.getKey())){
            // 仅异地寄存 + 有取件门店 + 派送中(4) 可核销
            if (!Constants.equalsInteger(order.getType(), Constants.ONE)) {
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "仅异地寄存订单支持司机核销");
            }
            if (order.getTakeShopId() == null) {
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "该订单无取件门店,无需司机核销");
            }
            if (!Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.delivering.getStatus())) {
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "当前订单状态不允许核销");
            }
            // 校验取件门店与当前登录门店一致
            if (!shopId.equals(order.getTakeShopId())) {
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "该订单不属于当前门店,无法核销");
            }
            // 派送中(4) → 已到店(5)
            order.setStatus(Constants.OrderStatus.arrived.getStatus());
            order.setArriveTime(new Date());
            if (StringUtils.isNotBlank(remark)) {
                order.setRemark(remark);
            }
            ordersMapper.updateById(order);
            // 释放司机核销码
            releaseVerifyCode(order.getDriverVerifyCode());
            // 保存附件(obj_type=3 门店入库图片,最多3张)
            saveVerifyImages(order.getId(), images, Constants.FileType.ORDER_TAKE.getKey(), order.getAcceptDriver());
            // 通知会员:订单已送达
            String destination = order.getTakeShopAddress() != null ? order.getTakeShopAddress() : "";
            if (order.getMemberVerifyCode() != null) {
                sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.ARRIVED_HAS_SHOP, order.getId(),
                        "orderNo", order.getCode(),
                        "destination", destination,
                        "pickupCode", order.getMemberVerifyCode());
            } else {
                sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.ARRIVED_NO_SHOP, order.getId(),
                        "orderNo", order.getCode(),
                        "destination", destination);
            }
            // 通知取件门店:订单已送达
            if (order.getTakeShopId() != null) {
                sendShopNotice(order.getTakeShopId(), Constants.ShopOrderNotify.ARRIVED, order.getId(),
                        "orderNo", order.getCode(),
                        "destination", destination);
            }
            // 短信通知会员:行李已送达
            Member arrivedMember = memberMapper.selectById(order.getMemberId());
            if (arrivedMember != null) {
                sendSmsNotify(arrivedMember.getTelephone(), Constants.SmsNotify.MEMBER_ARRIVED,
                        "orderNo", order.getCode(),
                        "address", destination,
                        "code", order.getMemberVerifyCode() != null ? order.getMemberVerifyCode() : "");
            }
        }else {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "当前订单状态不允许核销");
        }
    }
@@ -2914,12 +3028,13 @@
            ordersRefundMapper.insert(refundRecord);
            // 调用微信退款V3(放在最后,确保前置操作全部成功)
            String outRefundNo2 = ID.nextGUID();
            Refund refundResult = wxPayV3Service.refund(
                    order.getOutTradeNo(), order.getPayAmount(), order.getRefundAmount(),
                    outRefundNo2, order.getOutTradeNo(), order.getPayAmount(), order.getRefundAmount(),
                    "订单退款", wxPayProperties.getV3RefundNotifyUrl());
            // 退款成功后回填退款单号,标记退款中
            refundRecord.setRefundCode(refundResult.getOutRefundNo());
            refundRecord.setRefundCode(outRefundNo2);
            refundRecord.setStatus(Constants.ZERO); // 退款中
            ordersRefundMapper.updateById(refundRecord);
        }