|
|
@@ -8,7 +8,9 @@ import com.ruoyi.app.flashdelivery.dto.*;
|
|
|
import com.ruoyi.app.flashdelivery.route.FlashDeliveryRouteService;
|
|
|
import com.ruoyi.app.flashdelivery.route.GeoPoint;
|
|
|
import com.ruoyi.app.flashdelivery.route.RouteDistance;
|
|
|
+import com.ruoyi.common.core.domain.entity.SysDictData;
|
|
|
import com.ruoyi.common.exception.ServiceException;
|
|
|
+import com.ruoyi.common.utils.DictUtils;
|
|
|
import com.ruoyi.common.utils.MessageUtils;
|
|
|
import com.ruoyi.common.utils.StringUtils;
|
|
|
import com.ruoyi.system.domain.InfoUser;
|
|
|
@@ -168,16 +170,10 @@ public class FlashDeliveryApplicationService {
|
|
|
return participantDetail(order, true, false);
|
|
|
}
|
|
|
|
|
|
- public IPage<FlashDeliveryOrderView> userOrders(Long userId, int pageNum, int pageSize,
|
|
|
- String status, String scene, String serviceType) {
|
|
|
- if (hasText(status) && hasText(scene)) throw fail("flash.delivery.scene.invalid");
|
|
|
+ public IPage<FlashDeliveryUserOrderListView> userOrders(Long userId, int pageNum, int pageSize) {
|
|
|
QueryWrapper<FlashDeliveryOrder> query = new QueryWrapper<FlashDeliveryOrder>()
|
|
|
.eq("user_id", userId).orderByDesc("create_time");
|
|
|
- optionalEq(query, "status", status);
|
|
|
- applyUserScene(query, scene);
|
|
|
- validateOptionalServiceType(serviceType);
|
|
|
- optionalEq(query, "service_type", serviceType);
|
|
|
- return mapPage(orderMapper.selectPage(page(pageNum, pageSize), query), this::orderView);
|
|
|
+ return mapPage(orderMapper.selectPage(page(pageNum, pageSize), query), this::userOrderListView);
|
|
|
}
|
|
|
|
|
|
public FlashDeliveryOrderDetailView userDetail(Long userId, Long orderId) {
|
|
|
@@ -210,41 +206,43 @@ public class FlashDeliveryApplicationService {
|
|
|
writeLog(orderId, DELIVERED, COMPLETED, "USER", userId, null, now);
|
|
|
}
|
|
|
|
|
|
- public IPage<FlashDeliveryAvailableOrderView> available(Long riderId, int pageNum, int pageSize,
|
|
|
- String serviceType) {
|
|
|
+ public FlashDeliveryRiderOrderPageView riderOrders(Long riderId, int pageNum, int pageSize,
|
|
|
+ String tab, BigDecimal longitude, BigDecimal latitude) {
|
|
|
requireRider(riderId);
|
|
|
- validateOptionalServiceType(serviceType);
|
|
|
- QueryWrapper<FlashDeliveryOrder> query = new QueryWrapper<FlashDeliveryOrder>()
|
|
|
- .eq("status", WAITING_ACCEPTANCE).isNull("rider_id")
|
|
|
- .and(item -> item.eq("delivery_mode", "NOW")
|
|
|
- .or().le("scheduled_pickup_start_at", new Date()));
|
|
|
- optionalEq(query, "service_type", serviceType);
|
|
|
- // 第一版不自动派单:加急单优先,其余订单按发布时间由骑手主动抢单。
|
|
|
- query.orderByAsc("case when service_type = 'URGENT' then 0 else 1 end", "create_time");
|
|
|
+ if (!hasText(tab)) throw fail("flash.delivery.tab.invalid");
|
|
|
+ String selectedTab = tab.trim();
|
|
|
+ // lambda 无法捕获被重新赋值的参数,统一改用仅 newTask 携带坐标的有效变量。
|
|
|
+ BigDecimal effectiveLongitude = "newTask".equals(selectedTab) ? longitude : null;
|
|
|
+ BigDecimal effectiveLatitude = "newTask".equals(selectedTab) ? latitude : null;
|
|
|
+ if ("newTask".equals(selectedTab)) {
|
|
|
+ validateRiderCoordinates(effectiveLongitude, effectiveLatitude);
|
|
|
+ }
|
|
|
+ QueryWrapper<FlashDeliveryOrder> query = riderOrdersQuery(riderId, selectedTab,
|
|
|
+ effectiveLongitude, effectiveLatitude, true);
|
|
|
IPage<FlashDeliveryOrder> orders = orderMapper.selectPage(page(pageNum, pageSize), query);
|
|
|
- Page<FlashDeliveryAvailableOrderView> result = new Page<>(orders.getCurrent(), orders.getSize(), orders.getTotal());
|
|
|
- result.setRecords(orders.getRecords().stream().map(this::availableView).toList());
|
|
|
+ FlashDeliveryRiderOrderPageView result = new FlashDeliveryRiderOrderPageView();
|
|
|
+ result.setRecords(orders.getRecords().stream()
|
|
|
+ .map(order -> riderOrderListView(order, effectiveLongitude, effectiveLatitude)).toList());
|
|
|
+ result.setTotal(orders.getTotal());
|
|
|
+ result.setCurrent(orders.getCurrent());
|
|
|
+ result.setSize(orders.getSize());
|
|
|
+ if ("newTask".equals(selectedTab)) {
|
|
|
+ result.setNearbyTaskCount(orders.getTotal());
|
|
|
+ QueryWrapper<FlashDeliveryOrder> maximumQuery = riderOrdersQuery(riderId, selectedTab,
|
|
|
+ effectiveLongitude, effectiveLatitude, false)
|
|
|
+ .select("MAX(amount)");
|
|
|
+ result.setHighestOrderAmount(firstLong(orderMapper.selectObjs(maximumQuery)));
|
|
|
+ }
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- public IPage<FlashDeliveryOrderView> riderOrders(Long riderId, int pageNum, int pageSize,
|
|
|
- String status, String scene) {
|
|
|
- requireRider(riderId);
|
|
|
- if (hasText(status) && hasText(scene)) throw fail("flash.delivery.scene.invalid");
|
|
|
- QueryWrapper<FlashDeliveryOrder> query = new QueryWrapper<FlashDeliveryOrder>()
|
|
|
- .eq("rider_id", riderId).orderByDesc("create_time");
|
|
|
- optionalEq(query, "status", status);
|
|
|
- applyRiderScene(query, scene);
|
|
|
- return mapPage(orderMapper.selectPage(page(pageNum, pageSize), query), this::orderView);
|
|
|
- }
|
|
|
-
|
|
|
- public Object riderDetail(Long riderId, Long orderId) {
|
|
|
+ public FlashDeliveryOrderDetailView riderDetail(Long riderId, Long orderId) {
|
|
|
requireRider(riderId);
|
|
|
FlashDeliveryOrder order = requireOrder(orderId);
|
|
|
if (WAITING_ACCEPTANCE.equals(order.getStatus()) && order.getRiderId() == null) {
|
|
|
if (!isAvailableAt(order, new Date())) throw fail("flash.delivery.order.not.found");
|
|
|
- // 未接单骑手只能看到白名单字段和近似坐标,联系人及精确地址在抢单成功后开放。
|
|
|
- return availableView(order);
|
|
|
+ // 接单前显示取送文字地址,但隐藏联系人、电话、精确坐标、实际 PIN 和履约图片。
|
|
|
+ return participantDetail(order, false, true);
|
|
|
}
|
|
|
if (!Objects.equals(riderId, order.getRiderId())) throw fail("flash.delivery.order.not.found");
|
|
|
return participantDetail(order, false, false);
|
|
|
@@ -566,30 +564,44 @@ public class FlashDeliveryApplicationService {
|
|
|
|
|
|
private FlashDeliveryOrderDetailView participantDetail(FlashDeliveryOrder order,
|
|
|
boolean userView,
|
|
|
- boolean hideEvidence) {
|
|
|
- FlashDeliveryOrderDetailView view = new FlashDeliveryOrderDetailView();
|
|
|
- view.setOrder(orderView(order));
|
|
|
+ boolean hideSensitiveFields) {
|
|
|
+ FlashDeliveryOrderDetailView view = detailOrderView(order, !hideSensitiveFields);
|
|
|
if (userView) {
|
|
|
view.setDeliveryPinCode(Boolean.TRUE.equals(order.getPinRequired()) ? order.getDeliveryPinCode() : null);
|
|
|
view.setRider(riderSummary(order));
|
|
|
}
|
|
|
- if (hideEvidence || order.getId() == null) {
|
|
|
- view.setImages(List.of());
|
|
|
- view.setLogs(List.of());
|
|
|
- } else {
|
|
|
- view.setImages(imageMapper.selectList(new QueryWrapper<FlashDeliveryOrderImage>()
|
|
|
- .eq("order_id", order.getId()).orderByAsc("proof_type", "sort_order"))
|
|
|
- .stream().map(this::imageView).toList());
|
|
|
- view.setLogs(logMapper.selectList(new QueryWrapper<FlashDeliveryOrderLog>()
|
|
|
- .eq("order_id", order.getId()).orderByAsc("create_time", "id"))
|
|
|
- .stream().map(this::logView).toList());
|
|
|
+ if (!hideSensitiveFields && order.getId() != null) {
|
|
|
+ groupImageUrls(view, imageMapper.selectList(new QueryWrapper<FlashDeliveryOrderImage>()
|
|
|
+ .eq("order_id", order.getId()).orderByAsc("proof_type", "sort_order")));
|
|
|
}
|
|
|
return view;
|
|
|
}
|
|
|
|
|
|
- private FlashDeliveryAvailableOrderView availableView(FlashDeliveryOrder order) {
|
|
|
- // 明确逐字段组装白名单 DTO,禁止直接复制订单实体造成未来新增敏感字段意外泄露。
|
|
|
- FlashDeliveryAvailableOrderView view = new FlashDeliveryAvailableOrderView();
|
|
|
+ private FlashDeliveryUserOrderListView userOrderListView(FlashDeliveryOrder order) {
|
|
|
+ FlashDeliveryUserOrderListView view = new FlashDeliveryUserOrderListView();
|
|
|
+ view.setId(order.getId());
|
|
|
+ view.setOrderNo(order.getOrderNo());
|
|
|
+ view.setServiceType(order.getServiceType());
|
|
|
+ view.setStatus(order.getStatus());
|
|
|
+ view.setPackageType(order.getPackageType());
|
|
|
+ view.setDeliveryMode(order.getDeliveryMode());
|
|
|
+ view.setScheduledPickupStartAt(order.getScheduledPickupStartAt());
|
|
|
+ view.setScheduledPickupEndAt(order.getScheduledPickupEndAt());
|
|
|
+ view.setPickupAddress(order.getPickupAddress());
|
|
|
+ view.setPickupDetailAddress(order.getPickupAddressDetail());
|
|
|
+ view.setDeliveryAddress(order.getDeliveryAddress());
|
|
|
+ view.setDeliveryDetailAddress(order.getDeliveryAddressDetail());
|
|
|
+ view.setEstimatedDurationSeconds(order.getEstimatedDurationSeconds());
|
|
|
+ view.setAmount(order.getAmount());
|
|
|
+ view.setCurrency(order.getCurrency());
|
|
|
+ view.setDeliveredAt(order.getDeliveredAt());
|
|
|
+ view.setCreateTime(order.getCreateTime());
|
|
|
+ return view;
|
|
|
+ }
|
|
|
+
|
|
|
+ private FlashDeliveryRiderOrderListView riderOrderListView(FlashDeliveryOrder order,
|
|
|
+ BigDecimal longitude, BigDecimal latitude) {
|
|
|
+ FlashDeliveryRiderOrderListView view = new FlashDeliveryRiderOrderListView();
|
|
|
view.setId(order.getId());
|
|
|
view.setOrderNo(order.getOrderNo());
|
|
|
view.setServiceType(order.getServiceType());
|
|
|
@@ -599,14 +611,13 @@ public class FlashDeliveryApplicationService {
|
|
|
view.setDeliveryMode(order.getDeliveryMode());
|
|
|
view.setScheduledPickupStartAt(order.getScheduledPickupStartAt());
|
|
|
view.setScheduledPickupEndAt(order.getScheduledPickupEndAt());
|
|
|
- view.setPickupCity(order.getPickupCity());
|
|
|
- view.setPickupArea(order.getPickupArea());
|
|
|
- view.setDeliveryCity(order.getDeliveryCity());
|
|
|
- view.setDeliveryArea(order.getDeliveryArea());
|
|
|
- view.setPickupLatitudeApprox(approximate(order.getPickupLatitude()));
|
|
|
- view.setPickupLongitudeApprox(approximate(order.getPickupLongitude()));
|
|
|
- view.setDeliveryLatitudeApprox(approximate(order.getDeliveryLatitude()));
|
|
|
- view.setDeliveryLongitudeApprox(approximate(order.getDeliveryLongitude()));
|
|
|
+ view.setPinRequired(order.getPinRequired());
|
|
|
+ view.setPickupAddress(order.getPickupAddress());
|
|
|
+ view.setPickupDetailAddress(order.getPickupAddressDetail());
|
|
|
+ view.setDeliveryAddress(order.getDeliveryAddress());
|
|
|
+ view.setDeliveryDetailAddress(order.getDeliveryAddressDetail());
|
|
|
+ view.setPickupDistanceMeters(distanceMeters(longitude, latitude,
|
|
|
+ order.getPickupLongitude(), order.getPickupLatitude()));
|
|
|
view.setDistanceMeters(order.getDistanceMeters());
|
|
|
view.setEstimatedDurationSeconds(order.getEstimatedDurationSeconds());
|
|
|
view.setAmount(order.getAmount());
|
|
|
@@ -615,6 +626,26 @@ public class FlashDeliveryApplicationService {
|
|
|
return view;
|
|
|
}
|
|
|
|
|
|
+ private FlashDeliveryOrderDetailView detailOrderView(FlashDeliveryOrder order, boolean includeSensitiveFields) {
|
|
|
+ FlashDeliveryOrderDetailView view = new FlashDeliveryOrderDetailView();
|
|
|
+ populateOrderView(view, order, includeSensitiveFields);
|
|
|
+ return view;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void groupImageUrls(FlashDeliveryOrderDetailView view, List<FlashDeliveryOrderImage> images) {
|
|
|
+ List<String> sender = new ArrayList<>();
|
|
|
+ List<String> pickup = new ArrayList<>();
|
|
|
+ List<String> delivery = new ArrayList<>();
|
|
|
+ for (FlashDeliveryOrderImage image : images) {
|
|
|
+ if ("SENDER".equals(image.getProofType())) sender.add(image.getImageUrl());
|
|
|
+ else if ("PICKUP".equals(image.getProofType())) pickup.add(image.getImageUrl());
|
|
|
+ else if ("DELIVERY".equals(image.getProofType())) delivery.add(image.getImageUrl());
|
|
|
+ }
|
|
|
+ view.setSenderImageUrls(sender);
|
|
|
+ view.setPickupImageUrls(pickup);
|
|
|
+ view.setDeliveryImageUrls(delivery);
|
|
|
+ }
|
|
|
+
|
|
|
private FlashDeliveryServiceView serviceView(FlashDeliveryPricing pricing) {
|
|
|
FlashDeliveryServiceView view = new FlashDeliveryServiceView();
|
|
|
view.setServiceType(pricing.getServiceType());
|
|
|
@@ -630,8 +661,8 @@ public class FlashDeliveryApplicationService {
|
|
|
return view;
|
|
|
}
|
|
|
|
|
|
- private FlashDeliveryOrderView orderView(FlashDeliveryOrder order) {
|
|
|
- FlashDeliveryOrderView view = new FlashDeliveryOrderView();
|
|
|
+ private void populateOrderView(FlashDeliveryOrderView view, FlashDeliveryOrder order,
|
|
|
+ boolean includeSensitiveFields) {
|
|
|
view.setId(order.getId());
|
|
|
view.setOrderNo(order.getOrderNo());
|
|
|
view.setServiceType(order.getServiceType());
|
|
|
@@ -642,14 +673,14 @@ public class FlashDeliveryApplicationService {
|
|
|
view.setScheduledPickupStartAt(order.getScheduledPickupStartAt());
|
|
|
view.setScheduledPickupEndAt(order.getScheduledPickupEndAt());
|
|
|
view.setPinRequired(order.getPinRequired());
|
|
|
- view.setPickup(addressView(order, true));
|
|
|
- view.setDelivery(addressView(order, false));
|
|
|
+ view.setPickup(addressView(order, true, includeSensitiveFields));
|
|
|
+ view.setDelivery(addressView(order, false, includeSensitiveFields));
|
|
|
view.setDistanceMeters(order.getDistanceMeters());
|
|
|
view.setDistanceSource(order.getDistanceSource());
|
|
|
view.setEstimatedDurationSeconds(order.getEstimatedDurationSeconds());
|
|
|
view.setAmount(order.getAmount());
|
|
|
view.setCurrency(order.getCurrency());
|
|
|
- view.setUserNote(order.getUserNote());
|
|
|
+ view.setUserNote(includeSensitiveFields ? order.getUserNote() : null);
|
|
|
view.setAcceptedAt(order.getAcceptedAt());
|
|
|
view.setPickedUpAt(order.getPickedUpAt());
|
|
|
view.setDeliveredAt(order.getDeliveredAt());
|
|
|
@@ -658,42 +689,31 @@ public class FlashDeliveryApplicationService {
|
|
|
view.setCancelReason(order.getCancelReason());
|
|
|
view.setCreateTime(order.getCreateTime());
|
|
|
view.setUpdateTime(order.getUpdateTime());
|
|
|
- return view;
|
|
|
}
|
|
|
|
|
|
- private FlashDeliveryAddressView addressView(FlashDeliveryOrder order, boolean pickup) {
|
|
|
+ private FlashDeliveryAddressView addressView(FlashDeliveryOrder order, boolean pickup,
|
|
|
+ boolean includeSensitiveFields) {
|
|
|
FlashDeliveryAddressView view = new FlashDeliveryAddressView();
|
|
|
if (pickup) {
|
|
|
- view.setName(order.getPickupName()); view.setPhone(order.getPickupPhone());
|
|
|
+ view.setName(includeSensitiveFields ? order.getPickupName() : null);
|
|
|
+ view.setPhone(includeSensitiveFields ? order.getPickupPhone() : null);
|
|
|
view.setAddress(order.getPickupAddress()); view.setAddressDetail(order.getPickupAddressDetail());
|
|
|
view.setCity(order.getPickupCity()); view.setArea(order.getPickupArea());
|
|
|
view.setHandoffMethod(order.getPickupHandoffMethod());
|
|
|
- view.setLongitude(order.getPickupLongitude()); view.setLatitude(order.getPickupLatitude());
|
|
|
+ view.setLongitude(includeSensitiveFields ? order.getPickupLongitude() : null);
|
|
|
+ view.setLatitude(includeSensitiveFields ? order.getPickupLatitude() : null);
|
|
|
} else {
|
|
|
- view.setName(order.getDeliveryName()); view.setPhone(order.getDeliveryPhone());
|
|
|
+ view.setName(includeSensitiveFields ? order.getDeliveryName() : null);
|
|
|
+ view.setPhone(includeSensitiveFields ? order.getDeliveryPhone() : null);
|
|
|
view.setAddress(order.getDeliveryAddress()); view.setAddressDetail(order.getDeliveryAddressDetail());
|
|
|
view.setCity(order.getDeliveryCity()); view.setArea(order.getDeliveryArea());
|
|
|
view.setHandoffMethod(order.getDeliveryHandoffMethod());
|
|
|
- view.setLongitude(order.getDeliveryLongitude()); view.setLatitude(order.getDeliveryLatitude());
|
|
|
+ view.setLongitude(includeSensitiveFields ? order.getDeliveryLongitude() : null);
|
|
|
+ view.setLatitude(includeSensitiveFields ? order.getDeliveryLatitude() : null);
|
|
|
}
|
|
|
return view;
|
|
|
}
|
|
|
|
|
|
- private FlashDeliveryImageView imageView(FlashDeliveryOrderImage image) {
|
|
|
- FlashDeliveryImageView view = new FlashDeliveryImageView();
|
|
|
- view.setProofType(image.getProofType()); view.setImageUrl(image.getImageUrl());
|
|
|
- view.setSortOrder(image.getSortOrder()); view.setCreateTime(image.getCreateTime());
|
|
|
- return view;
|
|
|
- }
|
|
|
-
|
|
|
- private FlashDeliveryLogView logView(FlashDeliveryOrderLog log) {
|
|
|
- FlashDeliveryLogView view = new FlashDeliveryLogView();
|
|
|
- view.setFromStatus(log.getFromStatus()); view.setToStatus(log.getToStatus());
|
|
|
- view.setOperatorType(log.getOperatorType()); view.setReason(log.getReason());
|
|
|
- view.setCreateTime(log.getCreateTime());
|
|
|
- return view;
|
|
|
- }
|
|
|
-
|
|
|
private FlashDeliveryRiderSummaryView riderSummary(FlashDeliveryOrder order) {
|
|
|
if (order.getRiderId() == null) return null;
|
|
|
InfoUser rider = userMapper.selectInfoUserByUserId(order.getRiderId());
|
|
|
@@ -797,28 +817,94 @@ public class FlashDeliveryApplicationService {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- private void applyUserScene(QueryWrapper<FlashDeliveryOrder> query, String scene) {
|
|
|
- if (!hasText(scene) || "all".equals(scene)) return;
|
|
|
- switch (scene.trim()) {
|
|
|
- case "matching" -> query.eq("status", WAITING_ACCEPTANCE);
|
|
|
- case "progress" -> query.in("status", ACCEPTED, PICKED_UP, DELIVERED);
|
|
|
- case "done" -> query.eq("status", COMPLETED);
|
|
|
- case "cancelled" -> query.eq("status", CANCELLED);
|
|
|
- default -> throw fail("flash.delivery.scene.invalid");
|
|
|
+ private QueryWrapper<FlashDeliveryOrder> riderOrdersQuery(Long riderId, String tab,
|
|
|
+ BigDecimal longitude, BigDecimal latitude,
|
|
|
+ boolean orderResults) {
|
|
|
+ QueryWrapper<FlashDeliveryOrder> query = new QueryWrapper<>();
|
|
|
+ Date now = new Date();
|
|
|
+ switch (tab) {
|
|
|
+ case "newTask" -> {
|
|
|
+ query.eq("status", WAITING_ACCEPTANCE).isNull("rider_id")
|
|
|
+ .and(item -> item.eq("delivery_mode", "NOW")
|
|
|
+ .or().le("scheduled_pickup_start_at", now));
|
|
|
+ if (longitude != null) {
|
|
|
+ Integer limitKm = newTaskDistanceLimit();
|
|
|
+ if (limitKm != null) {
|
|
|
+ query.apply("ST_Distance_Sphere(point(pickup_longitude, pickup_latitude), point({0}, {1})) <= {2}",
|
|
|
+ longitude, latitude, limitKm.longValue() * 1000L);
|
|
|
+ }
|
|
|
+ if (orderResults) {
|
|
|
+ query.orderByAsc("ST_Distance_Sphere(point(pickup_longitude, pickup_latitude), point(" + longitude
|
|
|
+ + ", " + latitude + "))");
|
|
|
+ }
|
|
|
+ } else if (orderResults) {
|
|
|
+ query.orderByDesc("create_time");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ case "toPickup" -> {
|
|
|
+ query.eq("rider_id", riderId).eq("status", ACCEPTED);
|
|
|
+ if (orderResults) query.orderByAsc("create_time");
|
|
|
+ }
|
|
|
+ case "delivering" -> {
|
|
|
+ query.eq("rider_id", riderId).eq("status", PICKED_UP);
|
|
|
+ if (orderResults) query.orderByAsc("create_time");
|
|
|
+ }
|
|
|
+ case "completed" -> {
|
|
|
+ query.eq("rider_id", riderId).in("status", DELIVERED, COMPLETED);
|
|
|
+ if (orderResults) query.orderByDesc("create_time");
|
|
|
+ }
|
|
|
+ case "cancelled" -> {
|
|
|
+ query.eq("rider_id", riderId).eq("status", CANCELLED);
|
|
|
+ if (orderResults) query.orderByDesc("create_time");
|
|
|
+ }
|
|
|
+ default -> throw fail("flash.delivery.tab.invalid");
|
|
|
}
|
|
|
+ return query;
|
|
|
}
|
|
|
|
|
|
- private void applyRiderScene(QueryWrapper<FlashDeliveryOrder> query, String scene) {
|
|
|
- if (!hasText(scene) || "all".equals(scene)) return;
|
|
|
- switch (scene.trim()) {
|
|
|
- case "pickup" -> query.eq("status", ACCEPTED);
|
|
|
- case "delivering" -> query.eq("status", PICKED_UP);
|
|
|
- case "completed" -> query.in("status", DELIVERED, COMPLETED);
|
|
|
- case "cancelled" -> query.eq("status", CANCELLED);
|
|
|
- default -> throw fail("flash.delivery.scene.invalid");
|
|
|
+ private void validateRiderCoordinates(BigDecimal longitude, BigDecimal latitude) {
|
|
|
+ if ((longitude == null) != (latitude == null)
|
|
|
+ || longitude != null && (longitude.compareTo(BigDecimal.valueOf(-180)) < 0
|
|
|
+ || longitude.compareTo(BigDecimal.valueOf(180)) > 0
|
|
|
+ || latitude.compareTo(BigDecimal.valueOf(-90)) < 0
|
|
|
+ || latitude.compareTo(BigDecimal.valueOf(90)) > 0)) {
|
|
|
+ throw fail("flash.delivery.coordinates.invalid");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private Integer newTaskDistanceLimit() {
|
|
|
+ try {
|
|
|
+ List<SysDictData> values = DictUtils.getDictCache("sys_qs_newtask_distance");
|
|
|
+ if (values != null && !values.isEmpty()) {
|
|
|
+ int limit = Integer.parseInt(values.get(0).getDictValue());
|
|
|
+ return limit > 0 ? limit : null;
|
|
|
+ }
|
|
|
+ } catch (Exception ignored) {
|
|
|
+ // Keep the established rider-list behaviour: absent or malformed configuration disables distance filtering.
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Integer distanceMeters(BigDecimal longitude, BigDecimal latitude,
|
|
|
+ BigDecimal targetLongitude, BigDecimal targetLatitude) {
|
|
|
+ if (longitude == null || targetLongitude == null || targetLatitude == null) return null;
|
|
|
+ double latitudeRadians = Math.toRadians(latitude.doubleValue());
|
|
|
+ double targetLatitudeRadians = Math.toRadians(targetLatitude.doubleValue());
|
|
|
+ double latitudeDelta = targetLatitudeRadians - latitudeRadians;
|
|
|
+ double longitudeDelta = Math.toRadians(targetLongitude.doubleValue() - longitude.doubleValue());
|
|
|
+ double value = Math.sin(latitudeDelta / 2) * Math.sin(latitudeDelta / 2)
|
|
|
+ + Math.cos(latitudeRadians) * Math.cos(targetLatitudeRadians)
|
|
|
+ * Math.sin(longitudeDelta / 2) * Math.sin(longitudeDelta / 2);
|
|
|
+ return (int) Math.round(6_371_000D * 2D * Math.atan2(Math.sqrt(value), Math.sqrt(1D - value)));
|
|
|
+ }
|
|
|
+
|
|
|
+ private Long firstLong(List<Object> values) {
|
|
|
+ if (values == null || values.isEmpty() || values.get(0) == null) return null;
|
|
|
+ Object value = values.get(0);
|
|
|
+ if (value instanceof Number number) return number.longValue();
|
|
|
+ return Long.valueOf(String.valueOf(value));
|
|
|
+ }
|
|
|
+
|
|
|
private String normalizeDeliveryMode(String value) {
|
|
|
String mode = hasText(value) ? value.trim() : "NOW";
|
|
|
if (!DELIVERY_MODES.contains(mode)) throw fail("flash.delivery.mode.invalid");
|
|
|
@@ -851,7 +937,6 @@ public class FlashDeliveryApplicationService {
|
|
|
private boolean hasText(String value) { return StringUtils.isNotEmpty(value) && !value.trim().isEmpty(); }
|
|
|
private String trimToNull(String value) { return hasText(value) ? value.trim() : null; }
|
|
|
private boolean tooLong(String value, int max) { return value != null && value.trim().length() > max; }
|
|
|
- private BigDecimal approximate(BigDecimal value) { return value == null ? null : value.setScale(2, RoundingMode.HALF_UP); }
|
|
|
private boolean sameAddressText(FlashDeliveryAddressRequest left, FlashDeliveryAddressRequest right) {
|
|
|
return normalized(left.getAddress()).equals(normalized(right.getAddress()))
|
|
|
&& normalized(left.getAddressDetail()).equals(normalized(right.getAddressDetail()));
|