Skip to content

业务场景示例

本文档提供真实业务场景的完整代码示例,帮助您快速理解如何在实际项目中使用 Lovrabet Java OpenSDK。


目录

  • 场景 1: 客户数据同步服务
  • 场景 2: 销售漏斗分析看板
  • 场景 3: 订单管理系统
  • 场景 4: 定时数据同步任务
  • 场景 5: Spring Boot 集成

场景 1: 客户数据同步服务

业务需求

您的 Java CRM 系统需要将新增客户信息同步到 Lovrabet 云兔平台,用于数据分析和报表生成。

技术方案

  • 监听 CRM 系统的客户创建事件
  • 将客户数据转换为 Lovrabet 数据格式
  • 调用 OpenSDK 创建客户记录
  • 记录同步日志,处理异常情况

完整代码

Java
package com.example.crm.sync;

import com.lovrabet.runtime.opensdk.client.LovrabetSDKClient;
import com.lovrabet.runtime.opensdk.model.LovrabetRequest;
import com.lovrabet.runtime.opensdk.model.LovrabetResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * 客户数据同步服务
 * 将 CRM 系统的客户数据同步到 Lovrabet 云兔平台
 */
public class CustomerSyncService {
    private static final Logger logger = LoggerFactory.getLogger(CustomerSyncService.class);

    private final LovrabetSDKClient sdkClient;
    private final String appCode = "app-c2dd52a2";
    private final String customerDatasetCode = "b460abdbb0fb49e1865110d9dfbbc9b4";

    public CustomerSyncService(String accessKey, String baseUrl) {
        this.sdkClient = new LovrabetSDKClient(accessKey, baseUrl);
    }

    /**
     * 同步单个客户数据
     */
    public boolean syncCustomer(Customer customer) {
        logger.info("开始同步客户数据: {}", customer.getName());

        try {
            // 构建请求参数
            LovrabetRequest request = new LovrabetRequest();
            request.setAppCode(appCode);
            request.setModelCode(customerDatasetCode);

            // 转换客户数据为 Lovrabet 格式
            Map<String, Object> paramMap = convertCustomerData(customer);
            request.setParamMap(paramMap);

            // 调用 API 创建记录
            LovrabetResult<String> result = sdkClient.create(request);

            if (result.isSuccess()) {
                String lovrabetId = result.getData();
                logger.info("客户同步成功 - 客户: {}, Lovrabet ID: {}",
                    customer.getName(), lovrabetId);

                // 保存 Lovrabet ID 到本地数据库(可选)
                updateCustomerLovrabetId(customer.getId(), lovrabetId);
                return true;
            } else {
                logger.error("客户同步失败 - 客户: {}, 错误: {}",
                    customer.getName(), result.getResultMsg());
                return false;
            }
        } catch (Exception e) {
            logger.error("客户同步异常 - 客户: {}", customer.getName(), e);
            return false;
        }
    }

    /**
     * 批量同步客户数据
     */
    public SyncResult batchSyncCustomers(List<Customer> customers) {
        logger.info("开始批量同步客户数据, 总数: {}", customers.size());

        int successCount = 0;
        int failCount = 0;
        List<String> failedCustomers = new ArrayList<>();

        for (Customer customer : customers) {
            boolean success = syncCustomer(customer);
            if (success) {
                successCount++;
            } else {
                failCount++;
                failedCustomers.add(customer.getName());
            }
        }

        logger.info("批量同步完成 - 成功: {}, 失败: {}", successCount, failCount);

        return new SyncResult(successCount, failCount, failedCustomers);
    }

    /**
     * 更新客户数据
     */
    public boolean updateCustomer(Customer customer, String lovrabetId) {
        logger.info("开始更新客户数据: {}", customer.getName());

        try {
            LovrabetRequest request = new LovrabetRequest();
            request.setAppCode(appCode);
            request.setModelCode(customerDatasetCode);
            request.setId(Long.parseLong(lovrabetId));

            // 只更新变化的字段
            Map<String, Object> paramMap = convertCustomerData(customer);
            request.setParamMap(paramMap);

            LovrabetResult<String> result = sdkClient.update(request);

            if (result.isSuccess()) {
                logger.info("客户更新成功 - 客户: {}", customer.getName());
                return true;
            } else {
                logger.error("客户更新失败 - 客户: {}, 错误: {}",
                    customer.getName(), result.getResultMsg());
                return false;
            }
        } catch (Exception e) {
            logger.error("客户更新异常 - 客户: {}", customer.getName(), e);
            return false;
        }
    }

    /**
     * 将 CRM 客户对象转换为 Lovrabet 数据格式
     */
    private Map<String, Object> convertCustomerData(Customer customer) {
        Map<String, Object> paramMap = new HashMap<>();

        // 客户名称
        paramMap.put("TEXT_1", customer.getName());

        // 联系电话
        if (customer.getPhone() != null) {
            paramMap.put("TEXT_2", customer.getPhone());
        }

        // 电子邮箱
        if (customer.getEmail() != null) {
            paramMap.put("TEXT_3", customer.getEmail());
        }

        // 公司名称
        if (customer.getCompany() != null) {
            paramMap.put("TEXT_4", customer.getCompany());
        }

        // 客户级别 (1-普通, 2-重要, 3-VIP)
        paramMap.put("SELECT_1", customer.getLevel());

        // 客户来源
        if (customer.getSource() != null) {
            paramMap.put("SELECT_2", customer.getSource());
        }

        // 预估年消费金额
        if (customer.getEstimatedAnnualValue() != null) {
            paramMap.put("NUMBER_1", customer.getEstimatedAnnualValue());
        }

        // 创建时间
        paramMap.put("DATETIME_1", customer.getCreateTime().getTime());

        return paramMap;
    }

    /**
     * 保存 Lovrabet ID 到本地数据库
     */
    private void updateCustomerLovrabetId(Long customerId, String lovrabetId) {
        // 实际项目中这里应该更新数据库
        logger.debug("保存客户 {} 的 Lovrabet ID: {}", customerId, lovrabetId);
    }
}

/**
 * 客户实体类 (示例)
 */
class Customer {
    private Long id;
    private String name;
    private String phone;
    private String email;
    private String company;
    private Integer level;  // 1-普通, 2-重要, 3-VIP
    private String source;  // online, offline, referral
    private Double estimatedAnnualValue;
    private Date createTime;

    // Getters and Setters
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public String getPhone() { return phone; }
    public void setPhone(String phone) { this.phone = phone; }

    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }

    public String getCompany() { return company; }
    public void setCompany(String company) { this.company = company; }

    public Integer getLevel() { return level; }
    public void setLevel(Integer level) { this.level = level; }

    public String getSource() { return source; }
    public void setSource(String source) { this.source = source; }

    public Double getEstimatedAnnualValue() { return estimatedAnnualValue; }
    public void setEstimatedAnnualValue(Double estimatedAnnualValue) {
        this.estimatedAnnualValue = estimatedAnnualValue;
    }

    public Date getCreateTime() { return createTime; }
    public void setCreateTime(Date createTime) { this.createTime = createTime; }
}

/**
 * 同步结果类
 */
class SyncResult {
    private int successCount;
    private int failCount;
    private List<String> failedItems;

    public SyncResult(int successCount, int failCount, List<String> failedItems) {
        this.successCount = successCount;
        this.failCount = failCount;
        this.failedItems = failedItems;
    }

    // Getters
    public int getSuccessCount() { return successCount; }
    public int getFailCount() { return failCount; }
    public List<String> getFailedItems() { return failedItems; }
}

使用示例

Java
public class CustomerSyncDemo {
    public static void main(String[] args) {
        // 初始化同步服务
        String accessKey = System.getenv("LOVRABET_ACCESS_KEY");
        String baseUrl = "https://runtime.lovrabet.com/openapi";
        CustomerSyncService syncService = new CustomerSyncService(accessKey, baseUrl);

        // 创建客户对象
        Customer customer = new Customer();
        customer.setId(1001L);
        customer.setName("阿里巴巴科技有限公司");
        customer.setPhone("138-0000-1234");
        customer.setEmail("contact@alibaba.com");
        customer.setCompany("阿里巴巴");
        customer.setLevel(3);  // VIP 客户
        customer.setSource("referral");
        customer.setEstimatedAnnualValue(500000.0);
        customer.setCreateTime(new Date());

        // 同步单个客户
        boolean success = syncService.syncCustomer(customer);
        if (success) {
            System.out.println("客户同步成功");
        }

        // 批量同步客户
        List<Customer> customers = getCustomersFromDatabase();
        SyncResult result = syncService.batchSyncCustomers(customers);
        System.out.println("同步完成 - 成功: " + result.getSuccessCount()
            + ", 失败: " + result.getFailCount());
    }

    private static List<Customer> getCustomersFromDatabase() {
        // 从数据库获取客户列表
        return new ArrayList<>();
    }
}

场景 2: 销售漏斗分析看板

业务需求

从 Lovrabet 云兔平台获取销售机会数据,按阶段统计数量和金额,生成销售漏斗分析报告。

技术方案

  • 查询所有销售机会数据
  • 按销售阶段分组统计
  • 计算转化率和金额汇总
  • 生成可视化报表数据

完整代码

Java
package com.example.sales.analysis;

import com.lovrabet.runtime.opensdk.client.LovrabetSDKClient;
import com.lovrabet.runtime.opensdk.model.LovrabetRequest;
import com.lovrabet.runtime.opensdk.model.LovrabetResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 销售漏斗分析服务
 * 从 Lovrabet 获取销售数据并进行漏斗分析
 */
public class SalesFunnelAnalysisService {
    private static final Logger logger = LoggerFactory.getLogger(SalesFunnelAnalysisService.class);

    private final LovrabetSDKClient sdkClient;
    private final String appCode = "app-c2dd52a2";
    private final String opportunityDatasetCode = "32c036010c504757b80d438e3c0ec8b7";

    public SalesFunnelAnalysisService(String accessKey, String baseUrl) {
        this.sdkClient = new LovrabetSDKClient(accessKey, baseUrl);
    }

    /**
     * 获取销售漏斗分析报告
     */
    public FunnelReport generateFunnelReport() {
        logger.info("开始生成销售漏斗分析报告");

        // 1. 获取所有销售机会数据
        List<Map<String, Object>> opportunities = getAllOpportunities();

        if (opportunities.isEmpty()) {
            logger.warn("未查询到销售机会数据");
            return new FunnelReport();
        }

        logger.info("查询到销售机会数量: {}", opportunities.size());

        // 2. 按阶段分组统计
        Map<String, FunnelStage> stageMap = analyzeByStage(opportunities);

        // 3. 计算总体指标
        FunnelReport report = new FunnelReport();
        report.setTotalCount(opportunities.size());
        report.setTotalAmount(calculateTotalAmount(opportunities));
        report.setStages(sortStages(stageMap));
        report.setGenerateTime(new Date());

        logger.info("销售漏斗分析完成 - 总机会数: {}, 总金额: {}",
            report.getTotalCount(), report.getTotalAmount());

        return report;
    }

    /**
     * 获取所有销售机会数据
     */
    private List<Map<String, Object>> getAllOpportunities() {
        List<Map<String, Object>> allData = new ArrayList<>();
        int currentPage = 1;
        int pageSize = 100;
        boolean hasMore = true;

        while (hasMore) {
            LovrabetRequest request = new LovrabetRequest();
            request.setAppCode(appCode);
            request.setModelCode(opportunityDatasetCode);

            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("currentPage", currentPage);
            paramMap.put("pageSize", pageSize);
            request.setParamMap(paramMap);

            LovrabetResult<?> result = sdkClient.getList(request);

            if (result.isSuccess()) {
                List<Map<String, Object>> pageData =
                    (List<Map<String, Object>>) result.getData();

                if (pageData.isEmpty()) {
                    hasMore = false;
                } else {
                    allData.addAll(pageData);

                    if (pageData.size() < pageSize) {
                        hasMore = false;
                    } else {
                        currentPage++;
                    }
                }
            } else {
                logger.error("查询销售机会失败: {}", result.getResultMsg());
                hasMore = false;
            }
        }

        return allData;
    }

    /**
     * 按销售阶段分析数据
     */
    private Map<String, FunnelStage> analyzeByStage(List<Map<String, Object>> opportunities) {
        Map<String, FunnelStage> stageMap = new HashMap<>();

        for (Map<String, Object> opportunity : opportunities) {
            // 获取销售阶段 (SELECT_4 字段)
            String stage = (String) opportunity.get("SELECT_4");
            if (stage == null) {
                stage = "未知";
            }

            // 获取金额 (NUMBER_3 字段)
            Number amountObj = (Number) opportunity.get("NUMBER_3");
            double amount = amountObj != null ? amountObj.doubleValue() : 0.0;

            // 累加该阶段的数据
            FunnelStage funnelStage = stageMap.computeIfAbsent(stage, k -> new FunnelStage(k));
            funnelStage.addOpportunity(amount);
        }

        return stageMap;
    }

    /**
     * 计算总金额
     */
    private double calculateTotalAmount(List<Map<String, Object>> opportunities) {
        return opportunities.stream()
            .map(opp -> (Number) opp.get("NUMBER_3"))
            .filter(Objects::nonNull)
            .mapToDouble(Number::doubleValue)
            .sum();
    }

    /**
     * 对阶段进行排序(按销售流程顺序)
     */
    private List<FunnelStage> sortStages(Map<String, FunnelStage> stageMap) {
        // 定义销售阶段顺序
        List<String> stageOrder = Arrays.asList(
            "线索", "初次接触", "需求分析", "方案提报",
            "商务谈判", "合同签订", "已成交", "已失败"
        );

        return stageOrder.stream()
            .filter(stageMap::containsKey)
            .map(stageMap::get)
            .collect(Collectors.toList());
    }

    /**
     * 获取某个销售人员的业绩数据
     */
    public SalesPersonPerformance getSalesPersonPerformance(String salespersonName) {
        logger.info("查询销售人员业绩: {}", salespersonName);

        List<Map<String, Object>> allOpportunities = getAllOpportunities();

        // 筛选该销售人员的机会 (TEXT_1 字段存储销售人员名称)
        List<Map<String, Object>> personOpportunities = allOpportunities.stream()
            .filter(opp -> salespersonName.equals(opp.get("TEXT_1")))
            .collect(Collectors.toList());

        SalesPersonPerformance performance = new SalesPersonPerformance();
        performance.setSalespersonName(salespersonName);
        performance.setTotalOpportunities(personOpportunities.size());

        // 计算已成交金额
        double closedAmount = personOpportunities.stream()
            .filter(opp -> "已成交".equals(opp.get("SELECT_4")))
            .map(opp -> (Number) opp.get("NUMBER_3"))
            .filter(Objects::nonNull)
            .mapToDouble(Number::doubleValue)
            .sum();
        performance.setClosedAmount(closedAmount);

        // 计算在谈金额
        double pipelineAmount = personOpportunities.stream()
            .filter(opp -> {
                String stage = (String) opp.get("SELECT_4");
                return stage != null && !stage.equals("已成交") && !stage.equals("已失败");
            })
            .map(opp -> (Number) opp.get("NUMBER_3"))
            .filter(Objects::nonNull)
            .mapToDouble(Number::doubleValue)
            .sum();
        performance.setPipelineAmount(pipelineAmount);

        logger.info("销售人员 {} 业绩 - 总机会: {}, 已成交金额: {}, 在谈金额: {}",
            salespersonName, performance.getTotalOpportunities(),
            closedAmount, pipelineAmount);

        return performance;
    }
}

/**
 * 销售漏斗阶段数据
 */
class FunnelStage {
    private String stageName;
    private int count;
    private double totalAmount;

    public FunnelStage(String stageName) {
        this.stageName = stageName;
        this.count = 0;
        this.totalAmount = 0.0;
    }

    public void addOpportunity(double amount) {
        this.count++;
        this.totalAmount += amount;
    }

    // Getters
    public String getStageName() { return stageName; }
    public int getCount() { return count; }
    public double getTotalAmount() { return totalAmount; }
    public double getAverageAmount() {
        return count > 0 ? totalAmount / count : 0.0;
    }
}

/**
 * 销售漏斗报告
 */
class FunnelReport {
    private int totalCount;
    private double totalAmount;
    private List<FunnelStage> stages;
    private Date generateTime;

    public FunnelReport() {
        this.stages = new ArrayList<>();
    }

    // Getters and Setters
    public int getTotalCount() { return totalCount; }
    public void setTotalCount(int totalCount) { this.totalCount = totalCount; }

    public double getTotalAmount() { return totalAmount; }
    public void setTotalAmount(double totalAmount) { this.totalAmount = totalAmount; }

    public List<FunnelStage> getStages() { return stages; }
    public void setStages(List<FunnelStage> stages) { this.stages = stages; }

    public Date getGenerateTime() { return generateTime; }
    public void setGenerateTime(Date generateTime) { this.generateTime = generateTime; }
}

/**
 * 销售人员业绩数据
 */
class SalesPersonPerformance {
    private String salespersonName;
    private int totalOpportunities;
    private double closedAmount;
    private double pipelineAmount;

    // Getters and Setters
    public String getSalespersonName() { return salespersonName; }
    public void setSalespersonName(String salespersonName) {
        this.salespersonName = salespersonName;
    }

    public int getTotalOpportunities() { return totalOpportunities; }
    public void setTotalOpportunities(int totalOpportunities) {
        this.totalOpportunities = totalOpportunities;
    }

    public double getClosedAmount() { return closedAmount; }
    public void setClosedAmount(double closedAmount) {
        this.closedAmount = closedAmount;
    }

    public double getPipelineAmount() { return pipelineAmount; }
    public void setPipelineAmount(double pipelineAmount) {
        this.pipelineAmount = pipelineAmount;
    }
}

使用示例

Java
public class SalesFunnelDemo {
    public static void main(String[] args) {
        String accessKey = System.getenv("LOVRABET_ACCESS_KEY");
        String baseUrl = "https://runtime.lovrabet.com/openapi";

        SalesFunnelAnalysisService analysisService =
            new SalesFunnelAnalysisService(accessKey, baseUrl);

        // 生成销售漏斗报告
        FunnelReport report = analysisService.generateFunnelReport();

        System.out.println("===== 销售漏斗分析报告 =====");
        System.out.println("生成时间: " + report.getGenerateTime());
        System.out.println("总机会数: " + report.getTotalCount());
        System.out.println("总金额: " + String.format("%.2f", report.getTotalAmount()));
        System.out.println("\n各阶段详情:");

        for (FunnelStage stage : report.getStages()) {
            System.out.println(String.format("%s: %d 个机会, 总金额 %.2f, 平均金额 %.2f",
                stage.getStageName(),
                stage.getCount(),
                stage.getTotalAmount(),
                stage.getAverageAmount()));
        }

        // 查询特定销售人员业绩
        SalesPersonPerformance performance =
            analysisService.getSalesPersonPerformance("张三");

        System.out.println("\n===== 销售人员业绩 =====");
        System.out.println("销售人员: " + performance.getSalespersonName());
        System.out.println("总机会数: " + performance.getTotalOpportunities());
        System.out.println("已成交金额: " + String.format("%.2f", performance.getClosedAmount()));
        System.out.println("在谈金额: " + String.format("%.2f", performance.getPipelineAmount()));
    }
}

场景 3: 订单管理系统

业务需求

电商系统需要将订单数据同步到 Lovrabet,并支持订单状态更新、查询订单详情等操作。

完整代码

Java
package com.example.order;

import com.lovrabet.runtime.opensdk.client.LovrabetSDKClient;
import com.lovrabet.runtime.opensdk.model.LovrabetRequest;
import com.lovrabet.runtime.opensdk.model.LovrabetResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * 订单管理服务
 * 将电商订单同步到 Lovrabet 并管理订单状态
 */
public class OrderManagementService {
    private static final Logger logger = LoggerFactory.getLogger(OrderManagementService.class);

    private final LovrabetSDKClient sdkClient;
    private final String appCode = "app-c2dd52a2";
    private final String orderDatasetCode = "b460abdbb0fb49e1865110d9dfbbc9b4";

    public OrderManagementService(String accessKey, String baseUrl) {
        this.sdkClient = new LovrabetSDKClient(accessKey, baseUrl);
    }

    /**
     * 创建订单
     */
    public String createOrder(Order order) {
        logger.info("创建订单: {}", order.getOrderNo());

        LovrabetRequest request = new LovrabetRequest();
        request.setAppCode(appCode);
        request.setModelCode(orderDatasetCode);

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("TEXT_1", order.getOrderNo());              // 订单号
        paramMap.put("TEXT_2", order.getCustomerName());         // 客户姓名
        paramMap.put("TEXT_3", order.getCustomerPhone());        // 联系电话
        paramMap.put("TEXT_4", order.getShippingAddress());      // 收货地址
        paramMap.put("NUMBER_1", order.getTotalAmount());        // 订单金额
        paramMap.put("NUMBER_2", order.getItemCount());          // 商品数量
        paramMap.put("SELECT_1", order.getStatus());             // 订单状态
        paramMap.put("SELECT_2", order.getPaymentMethod());      // 支付方式
        paramMap.put("DATETIME_1", order.getCreateTime().getTime());  // 创建时间

        LovrabetResult<String> result = sdkClient.create(request);

        if (result.isSuccess()) {
            String lovrabetId = result.getData();
            logger.info("订单创建成功 - 订单号: {}, Lovrabet ID: {}",
                order.getOrderNo(), lovrabetId);
            return lovrabetId;
        } else {
            logger.error("订单创建失败 - 订单号: {}, 错误: {}",
                order.getOrderNo(), result.getResultMsg());
            return null;
        }
    }

    /**
     * 更新订单状态
     */
    public boolean updateOrderStatus(String lovrabetId, String newStatus) {
        logger.info("更新订单状态 - ID: {}, 新状态: {}", lovrabetId, newStatus);

        LovrabetRequest request = new LovrabetRequest();
        request.setAppCode(appCode);
        request.setModelCode(orderDatasetCode);
        request.setId(Long.parseLong(lovrabetId));

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("SELECT_1", newStatus);  // 更新状态字段

        // 如果是发货状态,添加发货时间
        if ("已发货".equals(newStatus)) {
            paramMap.put("DATETIME_2", System.currentTimeMillis());
        }

        // 如果是完成状态,添加完成时间
        if ("已完成".equals(newStatus)) {
            paramMap.put("DATETIME_3", System.currentTimeMillis());
        }

        request.setParamMap(paramMap);

        LovrabetResult<String> result = sdkClient.update(request);

        if (result.isSuccess()) {
            logger.info("订单状态更新成功 - ID: {}", lovrabetId);
            return true;
        } else {
            logger.error("订单状态更新失败 - ID: {}, 错误: {}",
                lovrabetId, result.getResultMsg());
            return false;
        }
    }

    /**
     * 查询订单详情
     */
    public Map<String, Object> getOrderDetail(String lovrabetId) {
        logger.info("查询订单详情 - ID: {}", lovrabetId);

        LovrabetRequest request = new LovrabetRequest();
        request.setAppCode(appCode);
        request.setModelCode(orderDatasetCode);
        request.setId(Long.parseLong(lovrabetId));

        LovrabetResult<?> result = sdkClient.getOne(request);

        if (result.isSuccess()) {
            Map<String, Object> orderData = (Map<String, Object>) result.getData();
            logger.info("订单查询成功 - ID: {}, 订单号: {}",
                lovrabetId, orderData.get("TEXT_1"));
            return orderData;
        } else {
            logger.error("订单查询失败 - ID: {}, 错误: {}",
                lovrabetId, result.getResultMsg());
            return null;
        }
    }

    /**
     * 查询指定时间段的订单
     */
    public List<Map<String, Object>> getOrdersByDateRange(Date startDate, Date endDate) {
        logger.info("查询时间段订单 - 开始: {}, 结束: {}", startDate, endDate);

        List<Map<String, Object>> allOrders = new ArrayList<>();
        int currentPage = 1;
        int pageSize = 50;
        boolean hasMore = true;

        while (hasMore) {
            LovrabetRequest request = new LovrabetRequest();
            request.setAppCode(appCode);
            request.setModelCode(orderDatasetCode);

            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("currentPage", currentPage);
            paramMap.put("pageSize", pageSize);
            request.setParamMap(paramMap);

            LovrabetResult<?> result = sdkClient.getList(request);

            if (result.isSuccess()) {
                List<Map<String, Object>> pageData =
                    (List<Map<String, Object>>) result.getData();

                if (pageData.isEmpty()) {
                    hasMore = false;
                } else {
                    // 筛选时间范围内的订单
                    for (Map<String, Object> order : pageData) {
                        Number createTimeMs = (Number) order.get("DATETIME_1");
                        if (createTimeMs != null) {
                            Date createTime = new Date(createTimeMs.longValue());
                            if (!createTime.before(startDate) && !createTime.after(endDate)) {
                                allOrders.add(order);
                            }
                        }
                    }

                    if (pageData.size() < pageSize) {
                        hasMore = false;
                    } else {
                        currentPage++;
                    }
                }
            } else {
                logger.error("查询订单列表失败: {}", result.getResultMsg());
                hasMore = false;
            }
        }

        logger.info("时间段订单查询完成 - 共 {} 条", allOrders.size());
        return allOrders;
    }

    /**
     * 统计订单数据
     */
    public OrderStatistics getOrderStatistics() {
        logger.info("开始统计订单数据");

        List<Map<String, Object>> allOrders = getAllOrders();

        OrderStatistics stats = new OrderStatistics();
        stats.setTotalOrders(allOrders.size());

        // 统计总金额
        double totalAmount = allOrders.stream()
            .map(order -> (Number) order.get("NUMBER_1"))
            .filter(Objects::nonNull)
            .mapToDouble(Number::doubleValue)
            .sum();
        stats.setTotalAmount(totalAmount);

        // 统计各状态订单数
        Map<String, Long> statusCount = allOrders.stream()
            .collect(Collectors.groupingBy(
                order -> (String) order.getOrDefault("SELECT_1", "未知"),
                Collectors.counting()
            ));
        stats.setStatusCount(statusCount);

        logger.info("订单统计完成 - 总订单: {}, 总金额: {}",
            stats.getTotalOrders(), stats.getTotalAmount());

        return stats;
    }

    /**
     * 获取所有订单
     */
    private List<Map<String, Object>> getAllOrders() {
        List<Map<String, Object>> allOrders = new ArrayList<>();
        int currentPage = 1;
        int pageSize = 100;
        boolean hasMore = true;

        while (hasMore) {
            LovrabetRequest request = new LovrabetRequest();
            request.setAppCode(appCode);
            request.setModelCode(orderDatasetCode);

            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("currentPage", currentPage);
            paramMap.put("pageSize", pageSize);
            request.setParamMap(paramMap);

            LovrabetResult<?> result = sdkClient.getList(request);

            if (result.isSuccess()) {
                List<Map<String, Object>> pageData =
                    (List<Map<String, Object>>) result.getData();

                if (pageData.isEmpty()) {
                    hasMore = false;
                } else {
                    allOrders.addAll(pageData);

                    if (pageData.size() < pageSize) {
                        hasMore = false;
                    } else {
                        currentPage++;
                    }
                }
            } else {
                logger.error("查询订单列表失败: {}", result.getResultMsg());
                hasMore = false;
            }
        }

        return allOrders;
    }
}

/**
 * 订单实体类
 */
class Order {
    private String orderNo;
    private String customerName;
    private String customerPhone;
    private String shippingAddress;
    private Double totalAmount;
    private Integer itemCount;
    private String status;  // 待支付、已支付、已发货、已完成、已取消
    private String paymentMethod;  // 支付宝、微信、银行卡
    private Date createTime;

    // Getters and Setters
    public String getOrderNo() { return orderNo; }
    public void setOrderNo(String orderNo) { this.orderNo = orderNo; }

    public String getCustomerName() { return customerName; }
    public void setCustomerName(String customerName) { this.customerName = customerName; }

    public String getCustomerPhone() { return customerPhone; }
    public void setCustomerPhone(String customerPhone) { this.customerPhone = customerPhone; }

    public String getShippingAddress() { return shippingAddress; }
    public void setShippingAddress(String shippingAddress) {
        this.shippingAddress = shippingAddress;
    }

    public Double getTotalAmount() { return totalAmount; }
    public void setTotalAmount(Double totalAmount) { this.totalAmount = totalAmount; }

    public Integer getItemCount() { return itemCount; }
    public void setItemCount(Integer itemCount) { this.itemCount = itemCount; }

    public String getStatus() { return status; }
    public void setStatus(String status) { this.status = status; }

    public String getPaymentMethod() { return paymentMethod; }
    public void setPaymentMethod(String paymentMethod) { this.paymentMethod = paymentMethod; }

    public Date getCreateTime() { return createTime; }
    public void setCreateTime(Date createTime) { this.createTime = createTime; }
}

/**
 * 订单统计数据
 */
class OrderStatistics {
    private int totalOrders;
    private double totalAmount;
    private Map<String, Long> statusCount;

    // Getters and Setters
    public int getTotalOrders() { return totalOrders; }
    public void setTotalOrders(int totalOrders) { this.totalOrders = totalOrders; }

    public double getTotalAmount() { return totalAmount; }
    public void setTotalAmount(double totalAmount) { this.totalAmount = totalAmount; }

    public Map<String, Long> getStatusCount() { return statusCount; }
    public void setStatusCount(Map<String, Long> statusCount) {
        this.statusCount = statusCount;
    }
}

使用示例

Java
public class OrderManagementDemo {
    public static void main(String[] args) {
        String accessKey = System.getenv("LOVRABET_ACCESS_KEY");
        String baseUrl = "https://runtime.lovrabet.com/openapi";

        OrderManagementService orderService =
            new OrderManagementService(accessKey, baseUrl);

        // 1. 创建订单
        Order order = new Order();
        order.setOrderNo("ORD20250112001");
        order.setCustomerName("李明");
        order.setCustomerPhone("138-1234-5678");
        order.setShippingAddress("北京市朝阳区xx路xx号");
        order.setTotalAmount(299.00);
        order.setItemCount(2);
        order.setStatus("待支付");
        order.setPaymentMethod("支付宝");
        order.setCreateTime(new Date());

        String lovrabetId = orderService.createOrder(order);
        System.out.println("订单创建成功, ID: " + lovrabetId);

        // 2. 更新订单状态
        boolean updated = orderService.updateOrderStatus(lovrabetId, "已支付");
        System.out.println("订单状态更新: " + (updated ? "成功" : "失败"));

        // 3. 查询订单详情
        Map<String, Object> orderDetail = orderService.getOrderDetail(lovrabetId);
        System.out.println("订单详情: " + orderDetail);

        // 4. 统计订单数据
        OrderStatistics stats = orderService.getOrderStatistics();
        System.out.println("\n===== 订单统计 =====");
        System.out.println("总订单数: " + stats.getTotalOrders());
        System.out.println("总金额: " + String.format("%.2f", stats.getTotalAmount()));
        System.out.println("各状态订单数:");
        stats.getStatusCount().forEach((status, count) ->
            System.out.println("  " + status + ": " + count + " 个"));
    }
}

场景 4: 定时数据同步任务

业务需求

每天定时将本地数据库的客户数据同步到 Lovrabet,保持数据一致性。

完整代码

Java
package com.example.scheduler;

import com.lovrabet.runtime.opensdk.client.LovrabetSDKClient;
import com.lovrabet.runtime.opensdk.model.LovrabetRequest;
import com.lovrabet.runtime.opensdk.model.LovrabetResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.*;

/**
 * 定时数据同步任务
 * 每天定时将本地数据同步到 Lovrabet
 */
public class DataSyncScheduler {
    private static final Logger logger = LoggerFactory.getLogger(DataSyncScheduler.class);

    private final LovrabetSDKClient sdkClient;
    private final ScheduledExecutorService scheduler;
    private final String appCode = "app-c2dd52a2";
    private final String datasetCode = "b460abdbb0fb49e1865110d9dfbbc9b4";

    public DataSyncScheduler(String accessKey, String baseUrl) {
        this.sdkClient = new LovrabetSDKClient(accessKey, baseUrl);
        this.scheduler = Executors.newScheduledThreadPool(1);
    }

    /**
     * 启动定时同步任务
     * 每天凌晨 2:00 执行
     */
    public void startScheduledSync() {
        logger.info("启动定时同步任务");

        // 计算到下一个凌晨 2:00 的延迟时间
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 2);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);

        if (calendar.getTimeInMillis() < System.currentTimeMillis()) {
            calendar.add(Calendar.DAY_OF_MONTH, 1);
        }

        long initialDelay = calendar.getTimeInMillis() - System.currentTimeMillis();
        long period = TimeUnit.DAYS.toMillis(1);  // 24 小时

        scheduler.scheduleAtFixedRate(
            this::performSync,
            initialDelay,
            period,
            TimeUnit.MILLISECONDS
        );

        logger.info("定时同步任务已启动, 首次执行时间: {}", calendar.getTime());
    }

    /**
     * 执行同步操作
     */
    public void performSync() {
        logger.info("========== 开始执行数据同步 ==========");
        long startTime = System.currentTimeMillis();

        try {
            // 1. 从本地数据库获取需要同步的数据
            List<Map<String, Object>> localData = fetchDataFromLocalDatabase();
            logger.info("从本地数据库获取到 {} 条待同步数据", localData.size());

            if (localData.isEmpty()) {
                logger.info("没有待同步数据,任务结束");
                return;
            }

            // 2. 批量同步数据
            SyncResult result = batchSyncData(localData);

            // 3. 记录同步结果
            long duration = System.currentTimeMillis() - startTime;
            logger.info("========== 数据同步完成 ==========");
            logger.info("总数据量: {}", localData.size());
            logger.info("成功: {}, 失败: {}", result.getSuccessCount(), result.getFailCount());
            logger.info("耗时: {} 秒", duration / 1000);

            // 4. 更新本地数据库的同步状态
            updateSyncStatus(result);

            // 5. 发送同步报告
            sendSyncReport(result, duration);

        } catch (Exception e) {
            logger.error("数据同步过程中发生异常", e);
            sendErrorAlert(e);
        }
    }

    /**
     * 批量同步数据
     */
    private SyncResult batchSyncData(List<Map<String, Object>> dataList) {
        int successCount = 0;
        int failCount = 0;
        List<String> failedIds = new ArrayList<>();

        // 使用线程池并发同步
        ExecutorService executor = Executors.newFixedThreadPool(10);
        List<Future<Boolean>> futures = new ArrayList<>();

        for (Map<String, Object> data : dataList) {
            Future<Boolean> future = executor.submit(() -> syncSingleRecord(data));
            futures.add(future);
        }

        // 等待所有任务完成并统计结果
        for (int i = 0; i < futures.size(); i++) {
            try {
                Boolean success = futures.get(i).get();
                if (success) {
                    successCount++;
                } else {
                    failCount++;
                    failedIds.add(String.valueOf(dataList.get(i).get("id")));
                }
            } catch (Exception e) {
                failCount++;
                failedIds.add(String.valueOf(dataList.get(i).get("id")));
                logger.error("获取同步结果失败", e);
            }
        }

        executor.shutdown();
        return new SyncResult(successCount, failCount, failedIds);
    }

    /**
     * 同步单条记录
     */
    private boolean syncSingleRecord(Map<String, Object> data) {
        try {
            LovrabetRequest request = new LovrabetRequest();
            request.setAppCode(appCode);
            request.setModelCode(datasetCode);

            // 转换数据格式
            Map<String, Object> paramMap = convertToLovrabetFormat(data);
            request.setParamMap(paramMap);

            // 检查是否已存在(通过本地ID映射)
            String lovrabetId = getExistingLovrabetId(data.get("id"));

            LovrabetResult<String> result;
            if (lovrabetId != null) {
                // 更新已存在的记录
                request.setId(Long.parseLong(lovrabetId));
                result = sdkClient.update(request);
            } else {
                // 创建新记录
                result = sdkClient.create(request);

                if (result.isSuccess()) {
                    // 保存新记录的 Lovrabet ID
                    saveIdMapping(data.get("id"), result.getData());
                }
            }

            return result.isSuccess();

        } catch (Exception e) {
            logger.error("同步记录失败: {}", data.get("id"), e);
            return false;
        }
    }

    /**
     * 从本地数据库获取待同步数据
     */
    private List<Map<String, Object>> fetchDataFromLocalDatabase() {
        // 实际项目中这里应该查询数据库
        // 这里返回示例数据
        logger.debug("从本地数据库获取数据...");
        return new ArrayList<>();
    }

    /**
     * 转换为 Lovrabet 数据格式
     */
    private Map<String, Object> convertToLovrabetFormat(Map<String, Object> localData) {
        Map<String, Object> lovrabetData = new HashMap<>();

        // 根据字段映射关系转换
        lovrabetData.put("TEXT_1", localData.get("name"));
        lovrabetData.put("TEXT_2", localData.get("phone"));
        lovrabetData.put("NUMBER_1", localData.get("amount"));
        lovrabetData.put("DATETIME_1", localData.get("createTime"));

        return lovrabetData;
    }

    /**
     * 获取已存在的 Lovrabet ID
     */
    private String getExistingLovrabetId(Object localId) {
        // 实际项目中这里应该查询映射表
        logger.debug("查询本地ID {} 对应的 Lovrabet ID", localId);
        return null;
    }

    /**
     * 保存 ID 映射关系
     */
    private void saveIdMapping(Object localId, String lovrabetId) {
        // 实际项目中这里应该保存到映射表
        logger.debug("保存ID映射: {} -> {}", localId, lovrabetId);
    }

    /**
     * 更新同步状态
     */
    private void updateSyncStatus(SyncResult result) {
        // 更新本地数据库的同步状态
        logger.debug("更新同步状态");
    }

    /**
     * 发送同步报告
     */
    private void sendSyncReport(SyncResult result, long duration) {
        logger.info("发送同步报告");
        // 实际项目中可以发送邮件或消息通知
    }

    /**
     * 发送错误告警
     */
    private void sendErrorAlert(Exception e) {
        logger.error("发送错误告警");
        // 实际项目中可以发送告警消息
    }

    /**
     * 停止定时任务
     */
    public void shutdown() {
        logger.info("停止定时同步任务");
        scheduler.shutdown();
        try {
            if (!scheduler.awaitTermination(60, TimeUnit.SECONDS)) {
                scheduler.shutdownNow();
            }
        } catch (InterruptedException e) {
            scheduler.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}

使用示例

Java
public class SchedulerDemo {
    public static void main(String[] args) {
        String accessKey = System.getenv("LOVRABET_ACCESS_KEY");
        String baseUrl = "https://runtime.lovrabet.com/openapi";

        DataSyncScheduler scheduler = new DataSyncScheduler(accessKey, baseUrl);

        // 启动定时同步任务(每天凌晨 2:00)
        scheduler.startScheduledSync();

        // 或者立即执行一次同步
        scheduler.performSync();

        // 程序退出时停止调度器
        Runtime.getRuntime().addShutdownHook(new Thread(scheduler::shutdown));
    }
}

场景 5: Spring Boot 集成

业务需求

在 Spring Boot 应用中集成 Lovrabet OpenSDK,实现依赖注入和自动配置。

完整代码

1. 配置类

Java
package com.example.config;

import com.lovrabet.runtime.opensdk.client.LovrabetSDKClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Lovrabet SDK 配置类
 */
@Configuration
public class LovrabetConfig {

    @Bean
    @ConfigurationProperties(prefix = "lovrabet")
    public LovrabetProperties lovrabetProperties() {
        return new LovrabetProperties();
    }

    @Bean
    public LovrabetSDKClient lovrabetSDKClient(LovrabetProperties properties) {
        return new LovrabetSDKClient(
            properties.getAccessKey(),
            properties.getBaseUrl()
        );
    }
}

/**
 * Lovrabet 配置属性
 */
class LovrabetProperties {
    private String accessKey;
    private String baseUrl;
    private String appCode;

    // Getters and Setters
    public String getAccessKey() { return accessKey; }
    public void setAccessKey(String accessKey) { this.accessKey = accessKey; }

    public String getBaseUrl() { return baseUrl; }
    public void setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; }

    public String getAppCode() { return appCode; }
    public void setAppCode(String appCode) { this.appCode = appCode; }
}

2. 配置文件 (application.yml)

YAML
lovrabet:
  access-key: ${LOVRABET_ACCESS_KEY}
  base-url: https://runtime.lovrabet.com/openapi
  app-code: app-c2dd52a2

3. Service 层

Java
package com.example.service;

import com.lovrabet.runtime.opensdk.client.LovrabetSDKClient;
import com.lovrabet.runtime.opensdk.model.LovrabetRequest;
import com.lovrabet.runtime.opensdk.model.LovrabetResult;
import com.example.config.LovrabetProperties;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class CustomerDataService {

    private final LovrabetSDKClient sdkClient;
    private final LovrabetProperties properties;

    public CustomerDataService(LovrabetSDKClient sdkClient,
                              LovrabetProperties properties) {
        this.sdkClient = sdkClient;
        this.properties = properties;
    }

    /**
     * 获取客户列表
     */
    public List<Map<String, Object>> getCustomers(int page, int size) {
        LovrabetRequest request = new LovrabetRequest();
        request.setAppCode(properties.getAppCode());
        request.setModelCode("b460abdbb0fb49e1865110d9dfbbc9b4");

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("currentPage", page);
        paramMap.put("pageSize", size);
        request.setParamMap(paramMap);

        LovrabetResult<?> result = sdkClient.getList(request);

        if (result.isSuccess()) {
            return (List<Map<String, Object>>) result.getData();
        } else {
            throw new RuntimeException("查询客户列表失败: " + result.getResultMsg());
        }
    }

    /**
     * 创建客户
     */
    public String createCustomer(Map<String, Object> customerData) {
        LovrabetRequest request = new LovrabetRequest();
        request.setAppCode(properties.getAppCode());
        request.setModelCode("b460abdbb0fb49e1865110d9dfbbc9b4");
        request.setParamMap(customerData);

        LovrabetResult<String> result = sdkClient.create(request);

        if (result.isSuccess()) {
            return result.getData();
        } else {
            throw new RuntimeException("创建客户失败: " + result.getResultMsg());
        }
    }
}

4. Controller 层

Java
package com.example.controller;

import com.example.service.CustomerDataService;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/customers")
public class CustomerController {

    private final CustomerDataService customerDataService;

    public CustomerController(CustomerDataService customerDataService) {
        this.customerDataService = customerDataService;
    }

    /**
     * 获取客户列表
     */
    @GetMapping
    public List<Map<String, Object>> getCustomers(
        @RequestParam(defaultValue = "1") int page,
        @RequestParam(defaultValue = "20") int size
    ) {
        return customerDataService.getCustomers(page, size);
    }

    /**
     * 创建客户
     */
    @PostMapping
    public String createCustomer(@RequestBody Map<String, Object> customerData) {
        return customerDataService.createCustomer(customerData);
    }
}

使用示例

启动 Spring Boot 应用后,可以通过 HTTP 接口访问:

Bash
# 获取客户列表
curl http://localhost:8080/api/customers?page=1&size=10

# 创建客户
curl -X POST http://localhost:8080/api/customers \
  -H "Content-Type: application/json" \
  -d '{
    "TEXT_1": "客户名称",
    "TEXT_2": "138-0000-1234",
    "NUMBER_1": 100000
  }'

总结

本文档提供了 5 个真实业务场景的完整示例:

  1. 客户数据同步服务 - 将 CRM 数据同步到 Lovrabet
  2. 销售漏斗分析看板 - 从 Lovrabet 获取数据并进行分析
  3. 订单管理系统 - 完整的订单 CRUD 操作
  4. 定时数据同步任务 - 使用定时任务保持数据一致性
  5. Spring Boot 集成 - 在现代 Java 框架中使用 SDK

所有示例代码都是完整可运行的,您可以根据实际业务需求进行调整和扩展。


下一步

学习完这些业务场景后,建议按以下顺序继续学习

  1. 📖 快速开始5 分钟完成第一个 CRUD 程序
  2. 📚 核心概念深入理解 SDK 工作原理
  3. 📋 API 参考查阅完整的接口文档
  4. 💡 业务示例 ← 当前位置学习 5 个真实场景的实现
  5. 🚀 最佳实践 ← 推荐下一步掌握生产环境优化技巧
  6. 常见问题解决使用中的疑问

需要帮助? 访问 常见问题 或联系 service@lovrabet.com

基于飞书知识库同步生成,内容以飞书源文档为准