| | |
| | | |
| | | @Resource |
| | | private GDMapGeocodingUtil gdMapGeocodingUtil; |
| | | |
| | | @Resource |
| | | private XpPointClient xpPointClient; |
| | | |
| | |
| | | private double navigationPriceWavePercent; |
| | | |
| | | /** |
| | | * 后台可配置的偏好项编码,逗号分隔,如 SMART,TIME,PRICE |
| | | * 后台可配置的偏好项编码,逗号分隔,如 SMART,TIME,PRICE,AVOID_CONGESTION |
| | | */ |
| | | @Value("${navigation.route.preference.enabled-codes:SMART,TIME,PRICE}") |
| | | private String navigationPreferenceEnabledCodes; |
| | |
| | | throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION); |
| | | } |
| | | |
| | | List<RouteStrategyKind> kinds = buildStrategyKindsForPlanning(userId); |
| | | StrategyPlanningConfig planningConfig = buildStrategyKindsForPlanning(userId, routeAndFareDto.getOpenCityId()); |
| | | List<RouteStrategyKind> kinds = planningConfig.getKinds(); |
| | | Map<String, RouteVo> routeById = new LinkedHashMap<>(); |
| | | Map<String, Set<RouteStrategyKind>> strategiesById = new LinkedHashMap<>(); |
| | | for (RouteStrategyKind kind : kinds) { |
| | |
| | | RouteAndFareVo part = pricingForRoute(pricingDto, rv, xpPricing, userId); |
| | | RouteOptionVo opt = new RouteOptionVo(); |
| | | opt.setPathFingerprint(fid); |
| | | List<String> labels = new ArrayList<>(); |
| | | for (RouteStrategyKind k : Arrays.asList(RouteStrategyKind.SMART, RouteStrategyKind.TIME, RouteStrategyKind.PRICE)) { |
| | | if (kindsOnRoute.contains(k)) { |
| | | labels.add(k.getDisplayName()); |
| | | } |
| | | } |
| | | List<String> labels = RouteStrategyKind.orderedOf(kindsOnRoute).stream() |
| | | .map(kind -> resolveStrategyDisplayName(kind, planningConfig.getDisplayNames())) |
| | | .collect(Collectors.toList()); |
| | | opt.setStrategyLabels(labels); |
| | | opt.setPrimaryStrategyLabel(primary.getDisplayName()); |
| | | opt.setPrimaryStrategyLabel(resolveStrategyDisplayName(primary, planningConfig.getDisplayNames())); |
| | | opt.setPrimaryRoutePlanRule(primary.getAmapStrategy()); |
| | | opt.setRoute(part.getRoute()); |
| | | opt.setFareEstimate(part.getFareEstimate()); |
| | |
| | | public List<RoutePreferenceItemVo> listRoutePreferences(Long openCityId, String userId) { |
| | | Set<String> enabledCodes = parseEnabledPreferenceCodes(); |
| | | Optional<RouteStrategyKind> savedPref = resolveUserPreferredKind(userId); |
| | | Map<RouteStrategyKind, String> displayNames = buildStrategyKindsForPlanning(userId, openCityId).getDisplayNames(); |
| | | List<RoutePreferenceItemVo> list = new ArrayList<>(); |
| | | int i = 0; |
| | | for (RouteStrategyKind k : Arrays.asList(RouteStrategyKind.SMART, RouteStrategyKind.TIME, RouteStrategyKind.PRICE)) { |
| | | for (RouteStrategyKind k : RouteStrategyKind.orderedValues()) { |
| | | if (!enabledCodes.contains(k.name())) { |
| | | continue; |
| | | } |
| | | RoutePreferenceItemVo v = new RoutePreferenceItemVo(); |
| | | v.setCode(k.name()); |
| | | v.setName(k.getDisplayName()); |
| | | v.setName(resolveStrategyDisplayName(k, displayNames)); |
| | | v.setEnabled(true); |
| | | v.setSortOrder(i++); |
| | | v.setAmapStrategy(k.getAmapStrategy()); |
| | |
| | | } |
| | | } |
| | | if (set.isEmpty()) { |
| | | set.add(RouteStrategyKind.SMART.name()); |
| | | set.add(RouteStrategyKind.TIME.name()); |
| | | set.add(RouteStrategyKind.PRICE.name()); |
| | | for (RouteStrategyKind kind : RouteStrategyKind.defaultPreferenceKinds()) { |
| | | set.add(kind.name()); |
| | | } |
| | | } |
| | | return set; |
| | | } |
| | |
| | | /** |
| | | * 用户偏好策略优先请求,其余策略仍请求以便合并去重。 |
| | | */ |
| | | private List<RouteStrategyKind> buildStrategyKindsForPlanning(String userId) { |
| | | List<RouteStrategyKind> all = new ArrayList<>(); |
| | | private StrategyPlanningConfig buildStrategyKindsForPlanning(String userId, Long openCityId) { |
| | | Set<String> enabled = parseEnabledPreferenceCodes(); |
| | | for (RouteStrategyKind k : Arrays.asList(RouteStrategyKind.SMART, RouteStrategyKind.TIME, RouteStrategyKind.PRICE)) { |
| | | List<XpRoutePlan> xpRoutePlans = xpRoutePlanMapper.selectList(new LambdaQueryWrapper<XpRoutePlan>().eq(XpRoutePlan::getOpenCityId, openCityId)); |
| | | Map<RouteStrategyKind, String> displayNames = new LinkedHashMap<>(); |
| | | List<RouteStrategyKind> configuredKinds = new ArrayList<>(); |
| | | if (xpRoutePlans.isEmpty()) { |
| | | configuredKinds.addAll(RouteStrategyKind.defaultPreferenceKinds()); |
| | | } else { |
| | | for (XpRoutePlan xpRoutePlan : xpRoutePlans) { |
| | | Integer strategy = xpRoutePlan.getRoutePlanRule(); |
| | | if (strategy == null) { |
| | | continue; |
| | | } |
| | | RouteStrategyKind.fromAmapStrategy(strategy).ifPresent(kind -> { |
| | | configuredKinds.add(kind); |
| | | if (StringUtils.isNotBlank(xpRoutePlan.getPlanName())) { |
| | | displayNames.putIfAbsent(kind, xpRoutePlan.getPlanName().trim()); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | List<RouteStrategyKind> all = new ArrayList<>(); |
| | | for (RouteStrategyKind k : configuredKinds) { |
| | | if (enabled.contains(k.name())) { |
| | | all.add(k); |
| | | addIfAbsent(all, k); |
| | | } |
| | | } |
| | | if (all.isEmpty()) { |
| | | all.add(RouteStrategyKind.SMART); |
| | | all.add(resolveDefaultEnabledKind(enabled)); |
| | | } |
| | | Optional<RouteStrategyKind> pref = resolveUserPreferredKind(userId); |
| | | if (!pref.isPresent()) { |
| | | return all; |
| | | return new StrategyPlanningConfig(all, displayNames); |
| | | } |
| | | RouteStrategyKind p = pref.get(); |
| | | if (!all.contains(p)) { |
| | | return all; |
| | | return new StrategyPlanningConfig(all, displayNames); |
| | | } |
| | | List<RouteStrategyKind> ordered = new ArrayList<>(); |
| | | ordered.add(p); |
| | |
| | | ordered.add(k); |
| | | } |
| | | } |
| | | return ordered; |
| | | return new StrategyPlanningConfig(ordered, displayNames); |
| | | } |
| | | |
| | | private String resolveStrategyDisplayName(RouteStrategyKind kind, Map<RouteStrategyKind, String> displayNames) { |
| | | String configuredName = displayNames.get(kind); |
| | | return StringUtils.isNotBlank(configuredName) ? configuredName : kind.getDisplayName(); |
| | | } |
| | | |
| | | private void addIfAbsent(List<RouteStrategyKind> kinds, RouteStrategyKind kind) { |
| | | if (!kinds.contains(kind)) { |
| | | kinds.add(kind); |
| | | } |
| | | } |
| | | |
| | | private RouteStrategyKind resolveDefaultEnabledKind(Set<String> enabled) { |
| | | for (RouteStrategyKind kind : RouteStrategyKind.defaultPreferenceKinds()) { |
| | | if (enabled.contains(kind.name())) { |
| | | return kind; |
| | | } |
| | | } |
| | | for (RouteStrategyKind kind : RouteStrategyKind.orderedValues()) { |
| | | if (enabled.contains(kind.name())) { |
| | | return kind; |
| | | } |
| | | } |
| | | return RouteStrategyKind.SMART; |
| | | } |
| | | |
| | | private static final class StrategyPlanningConfig { |
| | | private final List<RouteStrategyKind> kinds; |
| | | private final Map<RouteStrategyKind, String> displayNames; |
| | | |
| | | private StrategyPlanningConfig(List<RouteStrategyKind> kinds, Map<RouteStrategyKind, String> displayNames) { |
| | | this.kinds = kinds; |
| | | this.displayNames = displayNames; |
| | | } |
| | | |
| | | private List<RouteStrategyKind> getKinds() { |
| | | return kinds; |
| | | } |
| | | |
| | | private Map<RouteStrategyKind, String> getDisplayNames() { |
| | | return displayNames; |
| | | } |
| | | } |
| | | |
| | | private Optional<RouteStrategyKind> resolveUserPreferredKind(String userId) { |