| | |
| | | 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; |
| | |
| | | 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 |
| | |
| | | // 无取件门店,校验存件点与自选取件点是否在同一城市 |
| | | 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(); |
| | |
| | | // 异地:取件点信息 |
| | | orders.setTakeShopId(dto.getTakeShopId()); |
| | | orders.setTakeLocation(takeLocationValue); |
| | | orders.setTakeLocationRemark(takeLocationValue); |
| | | orders.setTakeLat(takeLat); |
| | | orders.setTakeLgt(takeLgt); |
| | | orders.setIsUrgent(dto.getIsUrgent()); |
| | |
| | | // 就地:取件点同寄件店铺 |
| | | 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); |
| | |
| | | |
| | | 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()) { |
| | |
| | | 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(); |
| | | |
| | |
| | | |
| | | 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(); |
| | | |
| | |
| | | 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()); |
| | |
| | | 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); |
| | |
| | | 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); |
| | |
| | | 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)) { |
| | | // 退款成功 |
| | |
| | | } |
| | | } |
| | | 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(), |
| | |
| | | "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(), "当前订单状态不允许核销"); |
| | | } |
| | | } |
| | |
| | | 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); |
| | | } |