| | |
| | | import com.doumee.biz.system.OperationConfigBiz; |
| | | import com.doumee.biz.system.SystemDictDataBiz; |
| | | import com.doumee.config.wx.WxMiniConfig; |
| | | import com.doumee.config.wx.WxMiniUtilService; |
| | | import com.doumee.config.wx.WxPayProperties; |
| | | import com.doumee.config.wx.WxPayV3Service; |
| | | import com.wechat.pay.java.service.refund.model.Refund; |
| | | import com.doumee.core.constants.Constants; |
| | | import com.doumee.core.constants.ResponseStatus; |
| | | import com.doumee.core.exception.BusinessException; |
| | | import com.doumee.core.model.PageData; |
| | | import com.doumee.core.model.PageWrap; |
| | | import com.doumee.core.utils.DateUtil; |
| | | import com.doumee.core.utils.Tencent.MapUtil; |
| | | import com.doumee.core.utils.geocode.MapUtil; |
| | | import com.doumee.core.utils.Utils; |
| | | import com.doumee.dao.business.*; |
| | | import com.doumee.dao.business.model.*; |
| | |
| | | import com.doumee.dao.dto.MyOrderDTO; |
| | | import com.doumee.dao.dto.OrderItemDTO; |
| | | import com.doumee.dao.vo.*; |
| | | import com.doumee.service.business.NoticeService; |
| | | import com.doumee.service.business.OrderLogService; |
| | | import com.doumee.service.business.OrdersService; |
| | | import com.doumee.dao.business.model.Notice; |
| | | import com.doumee.service.business.AreasService; |
| | | import com.doumee.service.business.PricingRuleService; |
| | | import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest; |
| | | import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; |
| | | import com.github.binarywang.wxpay.exception.WxPayException; |
| | | import com.github.xiaoymin.knife4j.core.util.CollectionUtils; |
| | |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.context.request.RequestContextHolder; |
| | | import org.springframework.web.context.request.ServletRequestAttributes; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.net.InetAddress; |
| | | import java.net.UnknownHostException; |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 寄存订单信息Service实现 |
| | |
| | | @Autowired |
| | | private RevenueMapper revenueMapper; |
| | | |
| | | @Autowired |
| | | private WxMiniUtilService wxMiniUtilService; |
| | | |
| | | |
| | | @Autowired |
| | | private SystemUserMapper systemUserMapper; |
| | |
| | | |
| | | @Autowired |
| | | private AreasService areasService; |
| | | |
| | | @Autowired |
| | | private NoticeService noticeService; |
| | | |
| | | @Autowired |
| | | private WxPayV3Service wxPayV3Service; |
| | | |
| | | @Autowired |
| | | private WxPayProperties wxPayProperties; |
| | | |
| | | @Override |
| | | public Integer create(Orders orders) { |
| | |
| | | // 1. 调用腾讯地图距离矩阵API计算驾车距离 |
| | | String from = dto.getFromLat() + "," + dto.getFromLgt(); |
| | | String to = dto.getToLat() + "," + dto.getToLgt(); |
| | | JSONObject distanceResult = MapUtil.distanceSingle("driving", from, to); |
| | | JSONObject distanceResult = MapUtil.direction("driving", from, to); |
| | | BigDecimal distance = distanceResult.getBigDecimal("distance"); |
| | | // distance 单位为米,转为公里 |
| | | BigDecimal distanceKm = distance.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); |
| | |
| | | |
| | | // 5. 加急费用:物品价格 × 加急系数(字典 URGENT_COEFFICIENT) |
| | | long urgentFeeFen = 0L; |
| | | if (Boolean.TRUE.equals(dto.getUrgent())) { |
| | | String urgentRateStr = systemDictDataBiz.queryByCode( |
| | | Constants.OPERATION_CONFIG, Constants.OP_URGENT_COEFFICIENT).getCode(); |
| | | BigDecimal urgentRate = new BigDecimal(urgentRateStr); |
| | | urgentFeeFen = new BigDecimal(itemPriceTotal).multiply(urgentRate) |
| | | .setScale(0, RoundingMode.HALF_UP).longValue(); |
| | | } |
| | | String urgentRateStr = systemDictDataBiz.queryByCode( |
| | | Constants.OPERATION_CONFIG, Constants.OP_URGENT_COEFFICIENT).getCode(); |
| | | BigDecimal urgentRate = new BigDecimal(urgentRateStr); |
| | | urgentFeeFen = new BigDecimal(itemPriceTotal).multiply(urgentRate) |
| | | .setScale(0, RoundingMode.HALF_UP).longValue(); |
| | | |
| | | // 6. 总价格 = 物品价格 + 保价费用 + 加急费用 |
| | | long totalPrice = itemPriceTotal + insuranceFeeFen + urgentFeeFen; |
| | | // 6. 总价格 = 物品价格 + 保价费用 + 加急费用(加急时才包含加急费) |
| | | long totalPrice = itemPriceTotal + insuranceFeeFen; |
| | | if (Boolean.TRUE.equals(dto.getUrgent())) { |
| | | totalPrice += urgentFeeFen; |
| | | } |
| | | |
| | | PriceCalculateVO result = new PriceCalculateVO(); |
| | | result.setItemList(itemList); |
| | |
| | | takeLocationValue = takeShop.getAddress(); |
| | | } else if (dto.getTakeLat() != null && dto.getTakeLgt() != null && StringUtils.isNotBlank(dto.getTakeLocation())) { |
| | | // 无取件门店,校验存件点与自选取件点是否在同一城市 |
| | | if (MapUtil.isSameCity(depositShop.getLatitude(), depositShop.getLongitude(), |
| | | 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(); |
| | |
| | | if (member == null || StringUtils.isBlank(member.getOpenid())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "用户信息异常,无法发起支付"); |
| | | } |
| | | PayResponse payResponse = wxPay(orders, member.getOpenid(), Constants.OrdersAttach.STORAGE_ORDER); |
| | | PayResponse payResponse = wxPayV3(orders.getOutTradeNo(), orders.getTotalAmount(), orders.getId(), |
| | | member.getOpenid(), Constants.OrdersAttach.STORAGE_ORDER); |
| | | payResponse.setLockKey(lockKey); |
| | | return payResponse; |
| | | } |
| | |
| | | if (member == null || StringUtils.isBlank(member.getOpenid())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "用户信息异常,无法发起支付"); |
| | | } |
| | | return wxPay(orders, member.getOpenid(), Constants.OrdersAttach.STORAGE_ORDER); |
| | | return wxPayV3(orders.getOutTradeNo(), orders.getTotalAmount(), orders.getId(), |
| | | member.getOpenid(), Constants.OrdersAttach.STORAGE_ORDER); |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 唤起微信支付V3 |
| | | * |
| | | * @param outTradeNo 商户订单号 |
| | | * @param totalCents 支付金额(分) |
| | | * @param orderId 订单主键 |
| | | * @param openid 用户微信openid |
| | | * @param ordersAttach 订单支付类型 |
| | | * @return PayResponse 包含微信调起参数和订单主键 |
| | | */ |
| | | private PayResponse wxPayV3(String outTradeNo, Long totalCents, Integer orderId, |
| | | String openid, Constants.OrdersAttach ordersAttach) { |
| | | Map<String, String> payParams = wxPayV3Service.createOrder( |
| | | outTradeNo, |
| | | ordersAttach.getName(), |
| | | totalCents != null ? totalCents : 0L, |
| | | openid, |
| | | wxPayProperties.getV3NotifyUrl(), |
| | | ordersAttach.getKey() |
| | | ); |
| | | |
| | | PayResponse payResponse = new PayResponse(); |
| | | payResponse.setResponse(payParams); |
| | | payResponse.setOrderId(orderId); |
| | | return payResponse; |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | // 寄件门店占比:fieldA=0(企业寄)/1(个人寄) |
| | | int depositFieldA = Constants.equalsInteger(depositShop.getCompanyType(), Constants.ONE) ? Constants.ZERO : Constants.ONE; |
| | | BigDecimal depositShopRata = getRevenueShareRata(cityId, depositFieldA); |
| | | // 取件门店占比:fieldA=2(企业取)/3(个人取) |
| | | int takeFieldA = Constants.equalsInteger(takeShop.getCompanyType(), Constants.ONE) ? Constants.TWO : Constants.THREE; |
| | | BigDecimal takeShopRata = getRevenueShareRata(cityId, takeFieldA); |
| | | // 取件门店占比:无取件门店时比例为0 |
| | | BigDecimal takeShopRata = BigDecimal.ZERO; |
| | | if (takeShop != null) { |
| | | int takeFieldA = Constants.equalsInteger(takeShop.getCompanyType(), Constants.ONE) ? Constants.TWO : Constants.THREE; |
| | | takeShopRata = getRevenueShareRata(cityId, takeFieldA); |
| | | } |
| | | |
| | | // 计算薪酬(分):totalAmount 为分,rata 为比例值(如 0.15 表示 15%) |
| | | long driverFee = new BigDecimal(totalAmount).multiply(driverRata).longValue(); |
| | | long depositShopFee = new BigDecimal(totalAmount).multiply(depositShopRata).longValue(); |
| | | long takeShopFee = totalAmount - driverFee - depositShopFee; |
| | | long takeShopFee = new BigDecimal(totalAmount).multiply(takeShopRata).longValue(); |
| | | |
| | | orders.setDriverFee(driverFee); |
| | | orders.setDepositShopFee(depositShopFee); |
| | |
| | | refund.setCreateTime(now); |
| | | refund.setDeleted(Constants.ZERO); |
| | | |
| | | // 调用微信退款,全额退款 |
| | | String refundCode = wxMiniUtilService.wxRefund(order.getOutTradeNo(), order.getPayAmount(), order.getPayAmount()); |
| | | refund.setRefundCode(refundCode); |
| | | refund.setRefundTime(new Date()); |
| | | // 调用微信退款V3,全额退款 |
| | | Refund refundResult = wxPayV3Service.refund(order.getOutTradeNo(), order.getPayAmount(), order.getPayAmount(), |
| | | "订单退款", wxPayProperties.getV3RefundNotifyUrl()); |
| | | refund.setRefundCode(refundResult.getOutRefundNo()); |
| | | refund.setStatus(Constants.ZERO); // 退款中 |
| | | ordersRefundMapper.insert(refund); |
| | | |
| | | order.setStatus(Constants.OrderStatus.cancelled.getStatus()); |
| | |
| | | ordersMapper.updateById(order); |
| | | |
| | | saveCancelLog(order, "会员取消订单(待寄存,全额退款)", reason, memberId); |
| | | // 通知会员:退款中 |
| | | sendOrderNotice(memberId, Constants.MemberOrderNotify.REFUNDING, orderId, |
| | | "orderNo", order.getCode()); |
| | | return; |
| | | } |
| | | |
| | |
| | | order.setCancelTime(now); |
| | | ordersMapper.updateById(order); |
| | | saveCancelLog(order, "会员申请取消订单(已寄存/已接单)", reason, memberId); |
| | | // 通知存件门店:退款申请 |
| | | if (order.getDepositShopId() != null) { |
| | | sendShopNotice(order.getDepositShopId(), Constants.ShopOrderNotify.REFUNDING, orderId, |
| | | "orderNo", order.getCode()); |
| | | } |
| | | return; |
| | | } |
| | | |
| | |
| | | log.setCreateTime(new Date()); |
| | | log.setDeleted(Constants.ZERO); |
| | | orderLogService.create(log); |
| | | } |
| | | |
| | | /** |
| | | * 发送订单站内信通知 |
| | | */ |
| | | private void sendOrderNotice(Integer memberId, Constants.MemberOrderNotify notify, Integer orderId, String... params) { |
| | | Notice notice = new Notice(); |
| | | notice.setUserType(0); // 0=会员 |
| | | notice.setUserId(memberId); |
| | | notice.setTitle(notify.getTitle()); |
| | | notice.setContent(notify.format(params)); |
| | | notice.setObjId(orderId); |
| | | notice.setObjType(0); // 0=订单 |
| | | notice.setStatus(0); // 0=未读 |
| | | notice.setIsdeleted(Constants.ZERO); |
| | | notice.setCreateDate(new Date()); |
| | | noticeService.create(notice); |
| | | } |
| | | |
| | | /** |
| | | * 发送门店站内信通知 |
| | | */ |
| | | private void sendShopNotice(Integer shopId, Constants.ShopOrderNotify notify, Integer orderId, String... params) { |
| | | Notice notice = new Notice(); |
| | | notice.setUserType(2); // 2=门店 |
| | | notice.setUserId(shopId); |
| | | notice.setTitle(notify.getTitle()); |
| | | notice.setContent(notify.format(params)); |
| | | notice.setObjId(orderId); |
| | | notice.setObjType(0); // 0=订单 |
| | | notice.setStatus(0); // 0=未读 |
| | | notice.setIsdeleted(Constants.ZERO); |
| | | notice.setCreateDate(new Date()); |
| | | noticeService.create(notice); |
| | | } |
| | | |
| | | /** |
| | | * 通知存件门店和取件门店(订单完成/评价等) |
| | | */ |
| | | private void notifyBothShops(Orders order, Constants.ShopOrderNotify notify, String... params) { |
| | | if (order.getDepositShopId() != null) { |
| | | sendShopNotice(order.getDepositShopId(), notify, order.getId(), params); |
| | | } |
| | | if (order.getTakeShopId() != null) { |
| | | sendShopNotice(order.getTakeShopId(), notify, order.getId(), params); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | } |
| | | ordersMapper.updateById(order); |
| | | |
| | | // 通知会员:订单待核验 |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_VERIFY, order.getId(), |
| | | "orderNo", order.getCode(), |
| | | "storeCode", order.getMemberVerifyCode()); |
| | | |
| | | // 就地寄存订单:通知存件门店待核验 |
| | | if (Constants.ZERO.equals(order.getType()) && order.getDepositShopId() != null) { |
| | | sendShopNotice(order.getDepositShopId(), Constants.ShopOrderNotify.WAIT_VERIFY, order.getId(), |
| | | "orderNo", order.getCode()); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | otherOrders.setCreateTime(now); |
| | | otherOrdersMapper.insert(otherOrders); |
| | | |
| | | // 5. 唤起微信支付 |
| | | return wxPayForOtherOrder(otherOrders, member.getOpenid(), Constants.OrdersAttach.OVERDUE_FEE); |
| | | // 5. 唤起微信支付V3 |
| | | return wxPayV3(otherOrders.getOutTradeNo(), otherOrders.getPayAccount(), otherOrders.getId(), |
| | | member.getOpenid(), Constants.OrdersAttach.OVERDUE_FEE); |
| | | } |
| | | |
| | | @Override |
| | |
| | | otherOrders.setCreateTime(now); |
| | | otherOrdersMapper.insert(otherOrders); |
| | | |
| | | // 5. 唤起微信支付 |
| | | return wxPayForOtherOrder(otherOrders, member.getOpenid(), Constants.OrdersAttach.SHOP_DEPOSIT); |
| | | // 5. 唤起微信支付V3 |
| | | return wxPayV3(otherOrders.getOutTradeNo(), otherOrders.getPayAccount(), otherOrders.getId(), |
| | | member.getOpenid(), Constants.OrdersAttach.SHOP_DEPOSIT); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 通知相关门店:订单已结算 |
| | | notifyBothShops(order, Constants.ShopOrderNotify.SETTLED, |
| | | "orderNo", order.getCode(), |
| | | "amount", String.valueOf(Constants.getFormatMoney( |
| | | order.getTotalAmount() != null ? order.getTotalAmount() : 0L))); |
| | | } |
| | | } |
| | | |
| | |
| | | if (isRemote && order.getAcceptDriver() != null) { |
| | | updateTargetScore(Constants.THREE, order.getAcceptDriver()); |
| | | } |
| | | |
| | | // 通知会员:订单已评价 |
| | | sendOrderNotice(memberId, Constants.MemberOrderNotify.EVALUATED, order.getId(), |
| | | "orderNo", order.getCode()); |
| | | |
| | | // 通知存件门店和取件门店:订单已评价 |
| | | notifyBothShops(order, Constants.ShopOrderNotify.EVALUATED, |
| | | "orderNo", order.getCode()); |
| | | } |
| | | |
| | | /** |
| | |
| | | saveVerifyImages(order.getId(), images, Constants.FileType.ORDER_DEPOSIT.getKey(), shopId); |
| | | // 记录订单日志 |
| | | saveShopVerifyLog(order, "门店确认寄存", "门店【" + shopName + "】确认寄存", remark, shopId); |
| | | // 通知会员:门店核销成功 |
| | | if (Constants.equalsInteger(order.getType(), Constants.ONE)) { |
| | | // 异地寄存 → 待抢单 |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_GRAB, order.getId(), |
| | | "orderNo", order.getCode()); |
| | | } else { |
| | | // 就地寄存 → 待取件提醒 |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_PICKUP_REMIND, order.getId(), |
| | | "orderNo", order.getCode()); |
| | | } |
| | | } else if (Constants.equalsInteger(status, Constants.OrderStatus.arrived.getStatus())) { |
| | | // 异地寄存 + 无取件门店 → 无法核销(客户自取,无门店操作) |
| | | if (Constants.equalsInteger(order.getType(), Constants.ONE) && order.getTakeShopId() == null) { |
| | |
| | | generateRevenueRecords(order.getId()); |
| | | // 记录订单日志 |
| | | saveShopVerifyLog(order, "门店确认取件", "门店【" + shopName + "】确认取件,订单完成", remark, shopId); |
| | | // 通知会员:订单已完成 |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.FINISHED, order.getId(), |
| | | "orderNo", order.getCode()); |
| | | // 通知存件门店和取件门店:订单已完成 |
| | | String settleDays = operationConfigBiz.getConfig().getSettlementDate(); |
| | | notifyBothShops(order, Constants.ShopOrderNotify.FINISHED, |
| | | "orderNo", order.getCode(), |
| | | "settleDays", settleDays != null ? settleDays : "7"); |
| | | } else { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "当前订单状态不允许核销"); |
| | | } |
| | |
| | | refundRecord.setDeleted(Constants.ZERO); |
| | | ordersRefundMapper.insert(refundRecord); |
| | | |
| | | // 调用微信退款(放在最后,确保前置操作全部成功) |
| | | String refundCode = wxMiniUtilService.wxRefund( |
| | | order.getOutTradeNo(), order.getPayAmount(), order.getRefundAmount()); |
| | | // 调用微信退款V3(放在最后,确保前置操作全部成功) |
| | | Refund refundResult = wxPayV3Service.refund( |
| | | order.getOutTradeNo(), order.getPayAmount(), order.getRefundAmount(), |
| | | "订单退款", wxPayProperties.getV3RefundNotifyUrl()); |
| | | |
| | | // 退款成功后回填退款单号和时间 |
| | | refundRecord.setRefundCode(refundCode); |
| | | refundRecord.setRefundTime(new Date()); |
| | | // 退款成功后回填退款单号,标记退款中 |
| | | refundRecord.setRefundCode(refundResult.getOutRefundNo()); |
| | | refundRecord.setStatus(Constants.ZERO); // 退款中 |
| | | ordersRefundMapper.updateById(refundRecord); |
| | | } |
| | | |
| | |
| | | logInfo += ",退款" + Constants.getFormatMoney(order.getRefundAmount()) + "元"; |
| | | } |
| | | saveShopVerifyLog(order, "门店确认出库", logInfo, remark, shopId); |
| | | // 通知会员:订单已完成 |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.FINISHED, order.getId(), |
| | | "orderNo", order.getCode()); |
| | | // 通知存件门店和取件门店:订单已完成 |
| | | String settleDays = operationConfigBiz.getConfig().getSettlementDate(); |
| | | notifyBothShops(order, Constants.ShopOrderNotify.FINISHED, |
| | | "orderNo", order.getCode(), |
| | | "settleDays", settleDays != null ? settleDays : "7"); |
| | | } |
| | | |
| | | @Override |
| | |
| | | // 7. 生成收益记录 |
| | | calculateAndSaveOrderFees(orderId); |
| | | generateRevenueRecords(orderId); |
| | | |
| | | // 通知会员:订单已完成 |
| | | sendOrderNotice(memberId, Constants.MemberOrderNotify.FINISHED, orderId, |
| | | "orderNo", order.getCode()); |
| | | // 通知存件门店和取件门店:订单已完成 |
| | | String settleDays = operationConfigBiz.getConfig().getSettlementDate(); |
| | | notifyBothShops(order, Constants.ShopOrderNotify.FINISHED, |
| | | "orderNo", order.getCode(), |
| | | "settleDays", settleDays != null ? settleDays : "7"); |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | // 保存附件(obj_type=3 门店入库图片,最多3张) |
| | | saveVerifyImages(order.getId(), images, Constants.FileType.ORDER_TAKE.getKey(), driverId); |
| | | |
| | | // 通知会员:订单已送达 |
| | | 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); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | // 腾讯地图距离矩阵API计算实际距离 |
| | | String from = fromLat + "," + fromLng; |
| | | String to = toLat + "," + toLng; |
| | | JSONObject distanceResult = MapUtil.distanceSingle("driving", from, to); |
| | | JSONObject distanceResult = MapUtil.direction("driving", from, to); |
| | | |
| | | // 获取距离(米),转公里 |
| | | int distanceMeters = distanceResult.getIntValue("distance"); |