零售多平台订单的自动调度与骑手协同技术实践

问题背景

零售门店同时接入美团、饿了么、抖音小时达等多个外卖平台后,面临订单调度的"三重割裂":

割裂类型 具体表现 运营痛点
订单分散 各平台订单独立推送,店员需同时盯守3-4个APP 高峰期漏看订单,超时自动取消率8%+
调度低效 人工判断骑手位置、手动分配订单,平均耗时40秒/单 骑手空跑、取货等待时间长,投诉率上升
状态不同步 订单接单、出餐、骑手取货状态需人工在各平台分别操作 操作遗漏导致平台处罚,月均损失200-300元

中小商户亟需一套轻量级自动调度系统,实现"订单进来→自动分配骑手→状态同步平台"的闭环。本文聚焦该场景的技术实现,方案已在部分零售SaaS系统(如嘚嘚象)中验证,本文仅讨论可复用的技术架构与代码实践。

一、自动调度系统架构

1.1 整体架构设计

1.2 核心设计原则

原则 说明 技术实现
平台解耦 新增平台仅需扩展适配器,不修改调度核心 策略模式 + 适配器接口
骑手聚合 对接多家跑腿平台,自动选择最优服务商 服务商评分模型 + 备份路由
状态闭环 订单全生命周期自动同步,减少人工操作 状态机 + 异步回调
异常兜底 骑手拒单/超时自动重派,保障履约 超时检测 + 重试队列

二、订单聚合与标准化

2.1 多平台订单统一接入

采用适配器模式屏蔽平台差异,核心代码仅需实现OrderAdapter接口:

java 复制代码
// 订单适配器接口
public interface OrderAdapter {
    String getPlatformCode(); // meituan/eleme/douyin
    
    // 接收平台推送的原始订单
    UnifiedOrder convertToUnified(String rawOrder);
    
    // 回传订单状态至平台
    boolean syncStatus(String orderId, OrderStatus status, String reason);
}

// 美团订单适配器
@Component
@PlatformAdapter("meituan")
public class MeituanOrderAdapter implements OrderAdapter {
    
    @Override
    public String getPlatformCode() {
        return "meituan";
    }
    
    @Override
    public UnifiedOrder convertToUnified(String rawJson) {
        // 1. 验签(美团要求)
        if (!verifySignature(rawJson)) {
            throw new InvalidOrderException("美团订单验签失败");
        }
        
        // 2. 解析美团特有字段
        MeituanOrder mtOrder = JsonUtils.fromJson(rawJson, MeituanOrder.class);
        
        // 3. 转换为统一模型
        UnifiedOrder order = new UnifiedOrder();
        order.setPlatform("meituan");
        order.setOrderId(mtOrder.getOrderId());
        order.setStoreId(mtOrder.getStoreId());
        order.setTotalAmount(new BigDecimal(mtOrder.getTotalPrice()).divide(BigDecimal.valueOf(100))); // 美团单位为分
        order.setCustomerAddress(mtOrder.getAddress());
        order.setCustomerPhone(maskPhone(mtOrder.getPhone())); // 脱敏
        order.setItems(convertItems(mtOrder.getItems()));
        order.setCreateTime(LocalDateTime.parse(mtOrder.getCreateTime()));
        order.setExpectedArrivalTime(LocalDateTime.parse(mtOrder.getExpectArrivalTime()));
        
        // 4. 提取特殊字段:美团有"期望送达时间"
        order.setExtraField("expect_arrival_time", mtOrder.getExpectArrivalTime());
        
        return order;
    }
    
    @Override
    public boolean syncStatus(String orderId, OrderStatus status, String reason) {
        // 美团状态映射
        String mtStatus = mapToMeituanStatus(status);
        return meituanApiClient.updateOrderStatus(orderId, mtStatus, reason);
    }
    
    private String mapToMeituanStatus(OrderStatus status) {
        return switch (status) {
            case CONFIRMED -> "confirm";      // 已接单
            case PREPARING -> "preparing";    // 备餐中
            case PICKED_UP -> "dispatching";  // 骑手取货
            case DELIVERED -> "delivered";    // 已送达
            default -> "cancel";
        };
    }
}

// 饿了么订单适配器(类似实现)
@Component
@PlatformAdapter("eleme")
public class ElemeOrderAdapter implements OrderAdapter {
    // 饿了么特有逻辑:字段命名、状态码不同
}

2.2 订单去重与合并

同一用户在多平台下单可能导致重复,需基于"用户+地址+商品"做智能去重:

java 复制代码
@Component
public class OrderDeduplicator {
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    /**
     * 检查订单是否重复(5分钟内相同用户+地址+商品组合)
     */
    public boolean isDuplicate(UnifiedOrder order) {
        // 1. 生成去重Key:用户手机号(脱敏后6位) + 地址哈希 + 商品组合哈希
        String userKey = order.getCustomerPhone().substring(order.getCustomerPhone().length() - 6);
        String addressHash = DigestUtils.md5Hex(order.getCustomerAddress()).substring(0, 8);
        String itemsHash = DigestUtils.md5Hex(JsonUtils.toJson(order.getItems())).substring(0, 8);
        
        String dedupKey = String.format("dedup:%s:%s:%s", userKey, addressHash, itemsHash);
        
        // 2. Redis原子操作:SETNX + EXPIRE
        Boolean exists = redisTemplate.opsForValue().setIfAbsent(
            dedupKey, 
            order.getOrderId(), 
            5, TimeUnit.MINUTES
        );
        
        // SETNX返回false表示已存在(重复订单)
        return Boolean.FALSE.equals(exists);
    }
    
    /**
     * 合并相似订单(同一用户5分钟内多笔小额订单)
     * 适用场景:用户先下一单,发现漏买又下一单
     */
    public UnifiedOrder mergeSimilarOrders(List<UnifiedOrder> orders) {
        if (orders.size() <= 1) return null;
        
        // 1. 检查是否同一用户、同一地址、时间间隔<5分钟
        UnifiedOrder first = orders.get(0);
        boolean canMerge = orders.stream().allMatch(o -> 
            o.getCustomerPhone().equals(first.getCustomerPhone()) &&
            o.getCustomerAddress().equals(first.getCustomerAddress()) &&
            Duration.between(o.getCreateTime(), first.getCreateTime()).toMinutes() < 5
        );
        
        if (!canMerge) return null;
        
        // 2. 合并商品(相同商品数量累加)
        Map<String, OrderItem> mergedItems = new HashMap<>();
        for (UnifiedOrder order : orders) {
            for (OrderItem item : order.getItems()) {
                String skuId = item.getSkuId();
                if (mergedItems.containsKey(skuId)) {
                    OrderItem existing = mergedItems.get(skuId);
                    existing.setQuantity(existing.getQuantity() + item.getQuantity());
                } else {
                    mergedItems.put(skuId, item.deepCopy());
                }
            }
        }
        
        // 3. 生成合并订单
        UnifiedOrder merged = first.deepCopy();
        merged.setOrderId("MERGED_" + System.currentTimeMillis());
        merged.setItems(new ArrayList<>(mergedItems.values()));
        merged.setTotalAmount(orders.stream()
            .map(UnifiedOrder::getTotalAmount)
            .reduce(BigDecimal.ZERO, BigDecimal::add));
        merged.setExtraField("merged_order_ids", 
            orders.stream().map(UnifiedOrder::getOrderId).collect(Collectors.joining(",")));
        
        return merged;
    }
}

三、骑手智能调度算法

3.1 骑手位置实时管理

基于Redis Geo实现骑手位置实时更新与查询:

java 复制代码
@Component
public class RiderLocationManager {
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    // Redis Key: rider:geo -> 存储骑手地理位置
    //            rider:status:{riderId} -> 骑手状态(空闲/接单中/休息)
    
    /**
     * 更新骑手位置(骑手APP每30秒上报一次)
     */
    public void updateLocation(String riderId, double lng, double lat) {
        // 1. 更新Geo
        redisTemplate.opsForGeo().add(
            "rider:geo", 
            new Point(lng, lat), 
            riderId
        );
        
        // 2. 更新最后上报时间(用于判断是否离线)
        redisTemplate.opsForValue().set(
            "rider:last_update:" + riderId,
            String.valueOf(System.currentTimeMillis()),
            5, TimeUnit.MINUTES
        );
    }
    
    /**
     * 查询附近空闲骑手(3公里内)
     */
    public List<Rider> findNearbyRiders(String storeId, int maxCount) {
        // 1. 获取门店位置
        Store store = storeService.getStore(storeId);
        Circle circle = new Circle(new Point(store.getLng(), store.getLat()), 
                                 new Distance(3, Metrics.KILOMETERS));
        
        // 2. Geo查询 + 状态过滤
        GeoResults<RedisGeoCommands.GeoLocation<String>> results = 
            redisTemplate.opsForGeo().radius("rider:geo", circle, 
                RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs()
                    .includeCoordinates()
                    .includeDistance()
                    .sortAscending() // 按距离升序
                    .limit(maxCount));
        
        // 3. 过滤空闲骑手
        List<Rider> riders = new ArrayList<>();
        for (GeoResult<RedisGeoCommands.GeoLocation<String>> result : results) {
            String riderId = result.getContent().getName();
            
            // 检查骑手状态是否空闲
            String status = redisTemplate.opsForValue().get("rider:status:" + riderId);
            if ("IDLE".equals(status)) {
                Rider rider = new Rider();
                rider.setRiderId(riderId);
                rider.setDistance(result.getDistance().getValue()); // 距离(公里)
                rider.setLng(result.getContent().getPoint().getX());
                rider.setLat(result.getContent().getPoint().getY());
                riders.add(rider);
            }
        }
        
        return riders;
    }
    
    /**
     * 标记骑手接单(状态变更为BUSY)
     */
    public void markRiderBusy(String riderId, String orderId) {
        redisTemplate.opsForValue().set("rider:status:" + riderId, "BUSY", 30, TimeUnit.MINUTES);
        redisTemplate.opsForValue().set("rider:current_order:" + riderId, orderId);
    }
    
    /**
     * 标记骑手空闲(订单完成后)
     */
    public void markRiderIdle(String riderId) {
        redisTemplate.opsForValue().set("rider:status:" + riderId, "IDLE", 24, TimeUnit.HOURS);
        redisTemplate.delete("rider:current_order:" + riderId);
    }
}

3.2 订单分配算法

采用加权评分模型,综合距离、骑手负载、历史履约率:

java 复制代码
@Component
public class OrderAssigner {
    
    /**
     * 分配骑手(返回最优骑手ID)
     */
    public String assignRider(UnifiedOrder order) {
        // 1. 查询附近空闲骑手(3公里内,最多20人)
        List<Rider> nearbyRiders = riderLocationManager.findNearbyRiders(
            order.getStoreId(), 20
        );
        
        if (nearbyRiders.isEmpty()) {
            log.warn("附近无空闲骑手, orderId={}", order.getOrderId());
            return null; // 无骑手可用,后续走人工调度
        }
        
        // 2. 计算每个骑手的综合得分
        Map<String, Double> scores = new HashMap<>();
        for (Rider rider : nearbyRiders) {
            double score = calculateRiderScore(rider, order);
            scores.put(rider.getRiderId(), score);
        }
        
        // 3. 选择得分最高的骑手
        return scores.entrySet().stream()
            .max(Map.Entry.comparingByValue())
            .map(Map.Entry::getKey)
            .orElse(null);
    }
    
    /**
     * 计算骑手综合得分(0-100分)
     * 权重:距离40% + 负载30% + 履约率30%
     */
    private double calculateRiderScore(Rider rider, UnifiedOrder order) {
        // 1. 距离得分(越近得分越高,3公里内满分)
        double distanceScore = Math.max(0, 100 - rider.getDistance() * 20);
        
        // 2. 负载得分(当前订单数越少得分越高)
        int currentOrders = getCurrentOrderCount(rider.getRiderId());
        double loadScore = currentOrders == 0 ? 100 : 
                          currentOrders == 1 ? 80 : 
                          currentOrders == 2 ? 60 : 40;
        
        // 3. 履约率得分(近7天准时送达率)
        double fulfillmentRate = getFulfillmentRate(rider.getRiderId());
        double rateScore = fulfillmentRate * 100;
        
        // 4. 加权综合得分
        return distanceScore * 0.4 + loadScore * 0.3 + rateScore * 0.3;
    }
    
    private int getCurrentOrderCount(String riderId) {
        // 从Redis获取骑手当前订单数
        String countStr = redisTemplate.opsForValue().get("rider:order_count:" + riderId);
        return countStr == null ? 0 : Integer.parseInt(countStr);
    }
    
    private double getFulfillmentRate(String riderId) {
        // 从数据库查询近7天履约数据
        RiderStats stats = riderStatsMapper.getRecentStats(riderId, 7);
        if (stats.getTotalOrders() == 0) return 0.9; // 新骑手默认90%
        return (double) stats.getOnTimeDeliveries() / stats.getTotalOrders();
    }
}

四、跑腿平台聚合调度

4.1 多平台SDK统一封装

对接闪送、达达、顺丰同城等跑腿平台,封装统一调用接口:

java 复制代码
// 跑腿平台接口
public interface DeliveryPlatform {
    String getPlatformCode(); // shansong/dada/sf
    
    // 下单
    DeliveryOrder createOrder(DeliveryRequest request) throws DeliveryException;
    
    // 取消订单
    boolean cancelOrder(String deliveryOrderId);
    
    // 查询订单状态
    DeliveryStatus queryStatus(String deliveryOrderId);
}

// 闪送平台实现
@Component
@DeliveryPlatformType("shansong")
public class ShansongPlatform implements DeliveryPlatform {
    
    @Override
    public String getPlatformCode() {
        return "shansong";
    }
    
    @Override
    public DeliveryOrder createOrder(DeliveryRequest request) {
        // 1. 转换为闪送特有格式
        ShansongCreateOrderReq ssReq = convertToShansong(request);
        
        // 2. 调用闪送API
        ShansongCreateOrderResp resp = shansongClient.createOrder(ssReq);
        
        // 3. 转换为统一模型
        DeliveryOrder order = new DeliveryOrder();
        order.setPlatform("shansong");
        order.setDeliveryOrderId(resp.getOrderId());
        order.setRiderName(resp.getRiderName());
        order.setRiderPhone(resp.getRiderPhone());
        order.setEstimatedArrivalTime(resp.getEstimatedTime());
        order.setStatus("PICKING_UP"); // 闪送状态:取件中
        
        return order;
    }
    
    // ... 其他方法实现
}

// 达达平台实现(类似)
@Component
@DeliveryPlatformType("dada")
public class DadaPlatform implements DeliveryPlatform {
    // 达达特有逻辑
}

// 平台工厂
@Component
public class DeliveryPlatformFactory {
    
    @Autowired
    private List<DeliveryPlatform> platforms;
    
    private Map<String, DeliveryPlatform> platformMap;
    
    @PostConstruct
    public void init() {
        platformMap = platforms.stream()
            .collect(Collectors.toMap(DeliveryPlatform::getPlatformCode, Function.identity()));
    }
    
    public DeliveryPlatform getPlatform(String platformCode) {
        return platformMap.get(platformCode);
    }
}

4.2 智能路由策略

根据订单特性自动选择最优跑腿平台:

java 复制代码
@Component
public class DeliveryRouter {
    
    @Autowired
    private DeliveryPlatformFactory platformFactory;
    
    /**
     * 智能路由:选择最优跑腿平台
     */
    public String routePlatform(UnifiedOrder order) {
        // 1. 获取所有可用平台
        List<PlatformScore> scores = new ArrayList<>();
        
        // 2. 闪送:适合高客单价、紧急订单
        if (order.getTotalAmount().compareTo(BigDecimal.valueOf(50)) >= 0) {
            scores.add(new PlatformScore("shansong", 90)); // 高客单价优先闪送
        } else {
            scores.add(new PlatformScore("shansong", 60));
        }
        
        // 3. 达达:覆盖广、价格适中,基础分80
        scores.add(new PlatformScore("dada", 80));
        
        // 4. 顺丰同城:适合贵重商品,但价格高
        if (isValuableGoods(order)) {
            scores.add(new PlatformScore("sf", 85));
        } else {
            scores.add(new PlatformScore("sf", 50)); // 非贵重商品不优先
        }
        
        // 5. 实时价格查询(可选):调用各平台预估接口,选择最低价
        // scores.forEach(score -> {
        //     BigDecimal price = queryEstimatedPrice(score.getPlatform(), order);
        //     score.setPrice(price);
        //     score.adjustScoreByPrice(price); // 价格越低,分数越高
        // });
        
        // 6. 选择最高分平台
        return scores.stream()
            .max(Comparator.comparingDouble(PlatformScore::getScore))
            .map(PlatformScore::getPlatform)
            .orElse("dada"); // 默认达达
    }
    
    private boolean isValuableGoods(UnifiedOrder order) {
        // 判断是否含贵重商品(如成人用品中的高端品类、数码配件)
        return order.getItems().stream()
            .anyMatch(item -> item.getCategory() != null && 
                           item.getCategory().contains("高端") || 
                           item.getPrice().compareTo(BigDecimal.valueOf(100)) > 0);
    }
    
    @Data
    @AllArgsConstructor
    static class PlatformScore {
        private String platform;
        private double score;
        private BigDecimal price; // 可选:预估价格
        
        public void adjustScoreByPrice(BigDecimal price) {
            // 价格每高5元,分数-2分
            if (this.price != null) {
                double diff = price.subtract(this.price).doubleValue() / 5;
                this.score -= diff * 2;
            }
        }
    }
}

4.3 骑手拒单自动重派

骑手接单后可能拒单或超时未取货,需自动重派:

java 复制代码
@Component
public class AutoReassignService {
    
    // 订单状态机
    // PENDING → ASSIGNED → [RIDER_ACCEPTED | RIDER_REJECTED | TIMEOUT] → REASSIGNING → ...
    
    /**
     * 处理骑手拒单
     */
    @EventListener
    public void onRiderRejected(RiderRejectedEvent event) {
        String orderId = event.getOrderId();
        String rejectedRiderId = event.getRiderId();
        
        // 1. 标记骑手空闲
        riderLocationManager.markRiderIdle(rejectedRiderId);
        
        // 2. 记录拒单次数(防恶意拒单)
        incrementRejectionCount(rejectedRiderId);
        
        // 3. 重新分配骑手(排除刚拒单的骑手)
        Set<String> excludedRiders = new HashSet<>();
        excludedRiders.add(rejectedRiderId);
        
        String newRiderId = orderAssigner.assignRiderExcluding(orderId, excludedRiders);
        
        if (newRiderId != null) {
            assignOrderToRider(orderId, newRiderId);
        } else {
            // 无可用骑手,转人工调度
            alertService.notifyStore(orderId, "无可用骑手,请人工调度");
        }
    }
    
    /**
     * 处理取货超时(骑手接单后15分钟未取货)
     */
    @Scheduled(fixedDelay = 60000) // 每分钟检查
    public void checkPickupTimeout() {
        List<TimeoutOrder> timeoutOrders = orderMapper.findPickupTimeoutOrders(15); // 15分钟未取货
        
        for (TimeoutOrder order : timeoutOrders) {
            // 1. 取消当前骑手订单(调用跑腿平台API)
            deliveryService.cancelOrder(order.getDeliveryOrderId());
            
            // 2. 标记骑手空闲
            riderLocationManager.markRiderIdle(order.getRiderId());
            
            // 3. 重新分配
            String newRiderId = orderAssigner.assignRider(order.getUnifiedOrder());
            if (newRiderId != null) {
                assignOrderToRider(order.getOrderId(), newRiderId);
            }
        }
    }
    
    private void assignOrderToRider(String orderId, String riderId) {
        // 1. 调用跑腿平台下单
        DeliveryOrder deliveryOrder = deliveryService.createOrder(orderId, riderId);
        
        // 2. 更新订单状态
        orderService.updateStatus(orderId, "RIDER_ASSIGNED", 
            "骑手" + deliveryOrder.getRiderName() + "已接单");
        
        // 3. 标记骑手忙碌
        riderLocationManager.markRiderBusy(riderId, orderId);
        
        // 4. 通知门店(语音播报)
        voiceService.broadcast("骑手" + deliveryOrder.getRiderName() + "已接单,电话" + deliveryOrder.getRiderPhone());
    }
}

五、状态自动同步至外卖平台

订单状态变化需自动回传至美团、饿了么等平台,减少人工操作:

java 复制代码
@Component
public class OrderStatusSyncService {
    
    @Autowired
    private PlatformAdapterFactory platformAdapterFactory;
    
    /**
     * 订单状态变更事件监听
     */
    @EventListener
    @Async // 异步执行,避免阻塞主流程
    public void onOrderStatusChanged(OrderStatusChangedEvent event) {
        UnifiedOrder order = event.getOrder();
        OrderStatus newStatus = event.getNewStatus();
        
        // 1. 获取平台适配器
        OrderAdapter adapter = platformAdapterFactory.getAdapter(order.getPlatform());
        if (adapter == null) return;
        
        // 2. 映射状态并同步
        try {
            boolean success = adapter.syncStatus(order.getOrderId(), newStatus, event.getReason());
            
            if (!success) {
                // 同步失败,加入重试队列
                retryQueue.offer(new SyncRetryTask(order.getPlatform(), order.getOrderId(), newStatus));
            }
            
        } catch (Exception e) {
            log.error("状态同步失败, platform={}, orderId={}", 
                order.getPlatform(), order.getOrderId(), e);
            
            // 失败加入重试队列
            retryQueue.offer(new SyncRetryTask(order.getPlatform(), order.getOrderId(), newStatus));
        }
    }
    
    /**
     * 重试任务(指数退避)
     */
    @Scheduled(fixedDelay = 30000) // 每30秒检查重试队列
    public void processRetryQueue() {
        SyncRetryTask task = retryQueue.poll();
        if (task == null) return;
        
        // 指数退避:第1次10秒,第2次20秒,第3次40秒...
        if (System.currentTimeMillis() - task.getCreateTime() < task.getRetryInterval()) {
            retryQueue.offer(task); // 未到重试时间,放回队列
            return;
        }
        
        // 执行重试
        try {
            OrderAdapter adapter = platformAdapterFactory.getAdapter(task.getPlatform());
            boolean success = adapter.syncStatus(task.getOrderId(), task.getStatus(), "系统重试");
            
            if (!success && task.getRetryCount() < 3) {
                // 重试次数+1,间隔翻倍
                task.incrementRetry();
                retryQueue.offer(task);
            }
            // 超过3次放弃(避免无限重试)
            
        } catch (Exception e) {
            log.error("重试同步失败", e);
            if (task.getRetryCount() < 3) {
                task.incrementRetry();
                retryQueue.offer(task);
            }
        }
    }
}

六、实际落地要点

6.1 门店部署方案

组件 部署方式 说明
云端服务 公有云(2核4G) 订单聚合、调度算法、平台对接
门店终端 旧Android手机 + 普通音箱 语音播报骑手信息,无需专用硬件
网络要求 门店WiFi 仅需稳定上网,无特殊带宽要求
部署时间 <30分钟 扫码安装APP + 配置门店ID

6.2 异常场景处理

异常场景 处理策略 技术实现
骑手拒单 自动重派 + 拉黑高频拒单骑手 拒单计数器 + 黑名单
平台API故障 本地缓存订单 + 故障恢复后重试 本地队列 + 指数退避重试
网络中断 边缘端缓存订单,网络恢复后同步 SQLite本地存储
骑手失联 15分钟未取货自动取消并重派 定时任务扫描超时订单

总结

订单自动调度系统的技术价值在于用轻量级方案解决高频运营痛点,核心经验:

  1. 适配器模式解耦平台差异
    新增外卖平台或跑腿平台时,仅需扩展适配器实现类,调度核心逻辑零修改。
  2. 边缘轻量化设计
    门店端仅需旧手机运行轻量APP,负责语音播报与状态展示,核心调度在云端完成。
  3. 状态自动闭环
    从"订单到达→分配骑手→骑手取货→送达"全链路自动同步平台,人工操作减少80%。

该方案已在多家便利店、成人用品店落地验证,无需专用硬件投入,仅需复用门店现有手机+网络即可实现自动化调度。技术落地的关键不是追求算法最优,而是"在约束条件下提供稳定可用的解决方案"------对于中小商户,稳定、低成本、易维护比技术先进性更重要。

注:本文仅讨论订单自动调度的技术实现方案,所有组件基于开源技术栈。文中提及的行业实践(如部分零售SaaS系统采用类似架构)仅为技术存在性佐证,不构成商业产品推荐。实际部署需结合具体平台API规范与业务规则调整。

相关推荐
智能零售小白白3 小时前
零售多门店库存调拨优化:需求预测与路径规划的技术实现
java·开发语言·零售
思通数科多模态大模型2 天前
用AI技术构建无人巡店线下门店零售防损体系
大数据·人工智能·目标检测·计算机视觉·数据挖掘·语音识别·零售
The Open Group4 天前
零售巨头中的 TOGAF®:通过业务单元整合,实现统一增长
零售
班德先生4 天前
时尚零售增长新思路:从视觉到空间的沉浸式塑造
大数据·人工智能·零售
班德先生4 天前
时尚零售品牌增长密码:从VI视觉到SI空间的沉浸式打造
大数据·人工智能·零售
说私域5 天前
日本零售精髓赋能下 链动2+1模式驱动新零售本质回归与发展格局研究
人工智能·小程序·数据挖掘·回归·流量运营·零售·私域运营
晚烛7 天前
CANN + 物理信息神经网络(PINNs):求解偏微分方程的新范式
javascript·人工智能·flutter·html·零售
晚烛7 天前
CANN 赋能智慧医疗:构建合规、高效、可靠的医学影像 AI 推理系统
人工智能·flutter·零售
神策数据8 天前
打造 AI Growth Team: 以 Data + AI 重塑品牌零售增长范式
人工智能·零售